В этом примере приложения показано, как использовать DWR в приложении чата. Это приложение дает понять, что DWR делает разработку таких приложений для совместной работы очень простой.
Мы начинаем с создания нового проекта для нашей комнаты чата с именем проекта DWRChatRoom. Нам также нужно добавить файл dwr.jar в каталог lib и включить DWR в файле web.xml. Ниже приведен исходный код файла dwr.xml .
<?xml ver sion="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="Login">
<param name="class" value="chatroom.Login" />
</create>
<create creator="new" javascript="ChatRoomDatabase">
<param name="class" value="chatroom.ChatRoomDatabase" />
</create>
</allow>
</dwr>
Исходный код для web.xml выглядит следующим образом:
<?xml ver sion="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.
com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.
sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_
5.xsd" id="WebApp_ID" version="2.5">
<display-name>DWRChatRoom</display-name>
<servlet>
<display-name>DWR Servlet</display-name>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Разработка пользовательского интерфейса
Следующим шагом мы создадим файлы для презентации: таблицу стилей и файлы HTML / JSP . Для приложения требуются файлы таблиц стилей, loginFailed.html и index.jsp. Исходный код таблицы стилей выглядит следующим образом:
body{
margin:0;
padding:0;
line-height: 1.5em;
}
b{font-size: 110%;}
em{color: red;}
#topsection{
background: #EAEAEA;
height: 90px; /*Height of top section*/
}
#topsection h1{
margin: 0;
padding-top: 15px;
}
#contentwrapper{
float: left;
width: 100%;
}
#contentcolumn{
margin-left: 200px; /*Set left margin to LeftColumnWidth*/
}
#leftcolumn{
float: left;
width: 200px; /*Width of left column*/
margin-left: -100%;
background: #C8FC98;
}
#footer{
clear: left;
width: 100%;
background: black;
color: #FFF;
text-align: center;
padding: 4px 0;
}
#footer a{
color: #FFFF80;
}
.innertube{
margin: 10px; /*Margins for inner DIV inside each column (to provide padding)*/
margin-top: 0;
}
Наша первая страница — это страница входа.
Он находится в каталоге WebContent и называется index.jsp . Исходный код страницы приведен ниже:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Book Authoring</title>
<script type='text/javascript' src='/DWRChatroom/dwr/interface/Login.js'></script>
<script type='text/javascript' src='/DWRChatroom/dwr/engine.js'></script>
<script type='text/javascript' src='/DWRChatroom/dwr/util.js'></script>
<script type="text/javascript">
function login()
{
var userNameInput=dwr.util.byId('userName');
var userName=userNameInput.value;
Login.doLogin(userName,loginResult);
}
function loginResult(newPage)
{
window.location.href=newPage;
}
</script>
</head>
<body>
<h1>Book Authoring Sample</h1>
<table cellpadding="0" cellspacing="0">
<tr>
<td>User name:</td>
<td><input id="userName" type="text" size="30"></td>
</tr>
<tr>
<td> </td>
<td><input type="button" value="Login" onclick="login();return false;"></td>
</tr></table>
</body>
</html>
Экран входа в систему использует функцию DWR для обработки входа пользователя (классы Java представлены после веб-страниц). Функция loginResults открывает страницу сбоя или главную страницу в зависимости от результата операции входа.
Если Войти не удалось, очень простой loginFailed.html страница показана пользователю, thesource код , который выглядит следующим образом :
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
<title>Login failed</title>
</head>
<body>
<h2>Login failed.</h2>
</body>
</html>
Главная страница mainpage.jsp содержит всю клиентскую логику нашего приложения ChatRoom. Исходный код страницы выглядит следующим образом:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Chatroom</title>
<link href="styles.css" rel="stylesheet" type="text/css" />
<%
if (session.getAttribute("username") == null
|| session.getAttribute("username").equals("")) {
//if not logged in and trying to access this page
//do nothing, browser shows empty page
return;
}
%>
<script type='text/javascript' src='/DWRChatRoom/dwr/interface/Login.js'></script>
<script type='text/javascript' src='/DWRChatRoom/dwr/interface/ChatRoomDatabase.js'></script>
<script type='text/javascript' src='/DWRChatRoom/dwr/engine.js'></script>
<script type='text/javascript' src='/DWRChatRoom/dwr/util.js'></script>
<script type="text/javascript">
dwr.engine.setActiveReverseAjax(true);
function logout()
{
Login.doLogout(showLoginScreen);
}
function showLoginScreen()
{
window.location.href='index.jsp';
}
function showUsersOnline()
{
var cellFuncs = [
function(user) {
return '<i>'+user+'</i>';
}
];
Login.getUsersOnline({
callback:function(users)
{
dwr.util.removeAllRows('usersOnline');
dwr.util.addRows( "usersOnline",users, cellFuncs,
{ escapeHtml:false });
}
});
}
function getPreviousMessages()
{
ChatRoomDatabase.getChatContent({
callback:function(messages)
{
var chatArea=dwr.util.byId('chatArea');
var html="";
for(index in messages)
{
var msg=messages[index];
html+=msg;
}
chatArea.innerHTML=html;
var chatAreaHeight = chatArea.scrollHeight;
chatArea.scrollTop = chatAreaHeight;
}
});
}
function newMessage(message)
{
var chatArea=dwr.util.byId('chatArea');
var oldMessages=chatArea.innerHTML;
chatArea.innerHTML=oldMessages+message;
var chatAreaHeight = chatArea.scrollHeight;
chatArea.scrollTop = chatAreaHeight;
}
function sendMessageIfEnter(event)
{
if(event.keyCode == 13)
{
sendMessage();
}
}
function sendMessage()
{
var message=dwr.util.byId('messageText');
var messageText=message.value;
ChatRoomDatabase.postMessage(messageText);
message.value='';
}
</script>
</head>
<body onload="showUsersOnline();">
<div id="maincontainer">
<div id="topsection">
<div class="innertube">
<h1>Chatroom</h1>
<h4>Welcome <i><%=(String) session.getAttribute("username")%></i></h4>
</div>
</div>
<div id="contentwrapper">
<div id="contentcolumn">
<div id="chatArea" style="width: 600px; height: 300px; overflow: auto">
</div>
<div id="inputArea">
<h4>Send message</h4>
<input id="messageText" type="text" size="50"
onkeyup="sendMessageIfEnter(event);"><input type="button" value="Send msg"
onclick="sendMessage();">
</div>
</div>
</div>
<div id="leftcolumn">
<div class="innertube">
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<td><b>Users online</b></td>
</tr>
</thead>
<tbody id="usersOnline">
</tbody>
</table>
<input id="logoutButton" type="button" value="Logout"
onclick="logout();return false;"></div>
</div>
<div id="footer">Stylesheet by <a
href="http://www.dynamicdrive.com/style/">Dynamic Drive CSS
Library</a></div>
</div>
<script type="text/javascript">
getPreviousMessages();
</script>
</body>
</html>
Первая специфичная для комнаты чата функция JavaScript — это getPreviousMessages () . Эта функция вызывается в конце mainpage.jsp и извлекает предыдущие сообщения чата для этой комнаты чата.
Функция newMessage () вызывается серверным Java-кодом, когда новое сообщение публикуется в чате. Функция также прокручивает область чата автоматически, чтобы показать последнее сообщение.
Функции sendMessageIfEnter () и sendMessage () используются для отправки пользовательских сообщений на сервер. В HTML-коде есть поле ввода для текста сообщения, а функция sendMessageIfEnter () прослушивает события onkeyup в поле ввода. Если пользователь нажимает ввод, вызывается функция sendMessage () для отправки сообщения на сервер.
HTML-код включает в себя область чата указанного размера и с автоматической прокруткой.
Разработка кода Java
В приложении есть несколько классов Java.
Класс Login обрабатывает вход и выход пользователя из системы, а также отслеживает зарегистрированных пользователей. Исходный код класса Login выглядит следующим образом:
package chatroom;
import java.util.Collection;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.proxy.ScriptProxy;
public class Login {
public Login() {
}
public String doLogin(String userName) {
UserDatabase userDb=UserDatabase.getInstance();
if(!userDb.isUserLogged(userName)) {
userDb.login(userName);
WebContext webContext= WebContextFactory.get();
HttpServletRequest request = webContext.getHttpServletRequest();
HttpSession session=request.getSession();
session.setAttribute("username", userName);
String scriptId = webContext.getScriptSession().getId();
session.setAttribute("scriptSessionId", scriptId);
updateUsersOnline();
return "mainpage.jsp";
}
else {
return "loginFailed.html";
}
}
public void doLogout() {
try {
WebContext ctx = WebContextFactory.get();
HttpServletRequest request = ctx.getHttpServletRequest();
HttpSession session = request.getSession();
Util util = new Util();
String userName = util.getCurrentUserName(session);
UserDatabase.getInstance().logout(userName);
session.removeAttribute("username");
session.removeAttribute("scriptSessionId");
session.invalidate();
} catch (Exception e) {
System.out.println(e.toString());
}
updateUsersOnline();
}
private void updateUsersOnline() {
WebContext webContext= WebContextFactory.get();
ServletContext servletContext = webContext.getServletContext();
ServerContext serverContext = ServerContextFactory.get(servletContext);
webContext.getScriptSessionsByPage("");
String contextPath = servletContext.getContextPath();
if (contextPath != null) {
Collection<ScriptSession> sessions =
serverContext.getScriptSessionsByPage
(contextPath + "/mainpage.jsp");
ScriptProxy proxy = new ScriptProxy(sessions);
proxy.addFunctionCall("showUsersOnline");
}
}
public List<String> getUsersOnline() {
UserDatabase userDb=UserDatabase.getInstance();
return userDb.getLoggedInUsers();
}
}
Ниже приведен исходный код класса UserDatabase
package chatroom;
import java.util.List;
import java.util.Vector;
//this class holds currently logged in users
//there is no persistence
public class UserDatabase {
private static UserDatabase userDatabase=new UserDatabase();
private List<String> loggedInUsers=new Vector<String>();
private UserDatabase() {
}
public static UserDatabase getInstance() {
return userDatabase;
}
public List<String> getLoggedInUsers() {
return loggedInUsers;
}
public boolean isUserLogged(String userName) {
return loggedInUsers.contains(userName);
}
public void login(String userName) {
loggedInUsers.add(userName);
}
public void logout(String userName) {
loggedInUsers.remove(userName);
}
}
Класс Util используется классом Login и предоставляет вспомогательные методы для примера приложения. Исходный код для класса Util выглядит следующим образом:
package chatroom;
import java.util.Hashtable;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
public class Util {
public Util() {
}
public String getCurrentUserName() {
//get user name from session
WebContext ctx = WebContextFactory.get();
HttpServletRequest request = ctx.getHttpServletRequest();
HttpSession session=request.getSession();
return getCurrentUserName(session);
}
public String getCurrentUserName(HttpSession session) {
String userName=(String)session.getAttribute("username");
return userName;
}
}
Логика функциональности серверной комнаты чата находится в классе ChatRoomDatabase. Исходный код для ChatRoomDatabase выглядит следующим образом:
package chatroom;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import javax.servlet.ServletContext;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.proxy.ScriptProxy;
public class ChatRoomDatabase {
private static List<String> chatContent = new Vector<String>();
public ChatRoomDatabase() {
}
public void postMessage(String message) {
String user = (new Util()).getCurrentUserName();
if (user != null) {
Date time = new Date();
StringBuffer sb = new StringBuffer();
sb.append(time.toString());
sb.append(" <b><i>");
sb.append(user);
sb.append("</i></b>: ");
sb.append(message);
sb.append("<br/>");
String newMessage=sb.toString();
chatContent.add(newMessage);
postNewMessage(newMessage);
}
}
public List<String> getChatContent() {
return chatContent;
}
private ScriptProxy getScriptProxyForSessions() {
WebContext webContext = WebContextFactory.get();
ServletContext servletContext = webContext.getServletContext();
ServerContext serverContext = ServerContextFactory.get(servletContext);
webContext.getScriptSessionsByPage("");
String contextPath = servletContext.getContextPath();
if (contextPath != null) {
Collection<ScriptSession> sessions = serverContext
.getScriptSessionsByPage(contextPath + "/mainpage.jsp");
ScriptProxy proxy = new ScriptProxy(sessions);
return proxy;
}
return null;
}
public void postNewMessage(String newMessage) {
ScriptProxy proxy = getScriptProxyForSessions();
if (proxy != null) {
proxy.addFunctionCall("newMessage",newMessage);
}
}
}
Код чата удивительно прост. Содержимое чата хранится в векторе строк. Метод getChatContent () просто возвращает содержимое чата Vector в браузер.
Для получения дополнительной и бесплатной загрузки проекта проверьте справочный сайт: http://geekonjava.blogspot.com/2015/08/chat-application-using-java-dwr.html