本文结合李刚的《Ajax:基于j2ee宝典〉中的案例,结合ajax的prototype框架,web应用的struts框架,实现了一个简单的聊天室。
小弟初次学习ajax,希望各位高手指点。谢谢
下面是源代码:
1.ajax的源代码:
chat.js:
var name=document.form1.name.value;
var pass=document.form1.pass.value;
if(name=="")...{
window.alert("username must !");
document.form1.name.focus();
return false;
}
if(pass=="")...{
window.alert("password must!");
document.form1.pass.focus();
return false;
}
sendLogin(name,pass);
}
function enterHandler(event) ... {
var keyCode=event.keyCode?event.keyCode:event.which?event.which:event.charCode;
if(keyCode==13)...{
login();
}
}
function sendLogin(name,pass) ... {
var url="/chat/login.do";
params="name="+name+"&pass="+pass;
var myAjax=new Ajax.Request(url,...{method:"post",postBody:params,onComplete:showLogin});
}
function showLogin(request) ... {
var msg=request.responseXML.getElementsByTagName("res")[0].firstChild.data;
if(msg!="ok")...{
var wrong=$("wrong");
wrong.innerHTML=msg;
}else...{
window.location.href="/chat/chat.jsp";
}
}
// check username
function checkUsername() ... {
var name=$F("name");
if(name=="")...{
window.alert("username must!");
$("name").focus();
return false;
}else...{
var url="/chat/checkUsername.do";
params="name="+name;
var myAjax=new Ajax.Request(url,...{method:"post",postBody:params,onComplete:showCheck});
}
}
// show check result
function showCheck(request) ... {
var msg=request.responseXML.getElementsByTagName("check")[0].firstChild.data;
if(msg)...{
$("check").innerHTML=msg;
$("name").focus();
$("pass").value="";
}
}
// addUser
function addUser() ... {
var name=$F("name");
var pass=$F("pass");
if(name=="")...{
window.alert("username must!");
$("name").focus();
return false;
}
else if(pass=="")...{
window.alert("password must!");
$("pass").focus();
return false;
}
else if(pass.length<6 || pass.length>10)...{
window.alert("password length=6-10");
$("pass").focus();
return false;
}
else...{
var url="/chat/addUser.do";
var params="name="+name+"&pass="+pass;
var myAjax=new Ajax.Request(url,...{method:"post",postBody:params,onComplete:regSuccess});
}
}
function regSuccess(request) ... {
var reg=request.responseXML.getElementsByTagName("ok")[0].firstChild.data;
if(reg!="ok")...{
$("check").innerHTML=reg;
$("name").value="";
$("pass").value="";
}else...{
window.location.href="/chat/regSuccess.jsp";
}
}
// to login
function toLogin() ... {
setTimeout("successReg()",3000);
}
function successReg() ... {
window.location.href="/chat/login.jsp";
}
// send message
function sendMsg() ... {
var msg=$F("msg");
if(msg=="")...{
window.alert("message not null");
$("msg").focus();
return false;
}else...{
var url="/chat/addMsg.do";
var params="msg="+msg;
var myAjax=new Ajax.Request(url,...{method:"post",postBody:params,onComplete:showMsg});
$("msg").value="";
}
}
// atuo flush textarea
function sendEmptyMsg() ... {
var url="/chat/addMsg.do";
var myAjax=new Ajax.Request(url,...{method:"post",PostBody:null,onComplete:showMsg});
setTimeout("sendEmptyMsg()",800);
}
// get back messages and display in textarea
function showMsg(request) ... {
var msgs=request.responseXML.getElementsByTagName("msg")[0].firstChild.data;
$("area").value=msgs;
}
// enter key send message
function msgHandler(event) ... {
var keyCode=event.keyCode?event.keyCode:event.which?event.which:event.charCode;
if(keyCode==13)...{
sendMsg();
}
}
// leave chat room
function leaveRoom() ... {
var url="/chat/leaveRoom.do";
var myAjax=new Ajax.Request(url,...{method:"post",PostBody:null,onComplete:leave});
}
function leave() ... {
window.location.href="/chat/login.jsp";
}
2.jsp页面代码:
(1)login.jsp
<! 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=UTF-8" >
< link href ="CSS/style.css" rel ="stylesheet" type ="text/css" />
< script language ="JavaScript" src ="js/Chat.js" type ="text/javascript" ></ script >
< script language ="JavaScript" src ="js/prototype.js" type ="text/javascript" ></ script >
< title > Insert title here </ title >
</ head >
< body >
< form action ="" method ="Post" name ="form1" >
< table width ="300px" height ="200px" cellspacing ="0" cellpadding ="0" align ="center" border ="0" bgcolor ="#c0c0c0" >
< tr >< td colspan ="2" > </ td ></ tr >
< tr >< td colspan ="2" >< font color ="red" id ="wrong" ></ font ></ td ></ tr >
< tr >< td colspan ="2" align ="center" > 用户登录 </ td ></ tr >
< tr >< td align ="right" > 用户名: </ td >< td >< input type ="text" name ="name" maxlength ="20" size ="15" /></ td ></ tr >
< tr >< td align ="right" > 密 码: </ td >< td >< input type ="password" name ="pass" maxlength ="20" size ="15" onKeyPress ="enterHandler(event)" /></ td ></ tr >
< tr >< td colspan ="2" align ="center" >< input type ="button" value ="提交" class ="btn_grey" onclick ="login()" /> < input type ="reset" value ="重置" class ="btn_grey" /></ td ></ tr >
< tr >< td align ="center" colspan ="2" >< a href ="/chat/register.jsp" > 注册新用户 </ a ></ td ></ tr >
</ table >
</ form >
</ body >
</ html >
(2)register.jsp
<! 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=UTF-8" >
< link href ="CSS/style.css" rel ="stylesheet" type ="text/css" >
< script language ="JavaScript" src ="js/Chat.js" type ="text/javascript" ></ script >
< script language ="JavaScript" src ="js/prototype.js" type ="text/javascript" ></ script >
< title > Insert title here </ title >
</ head >
< body >
< form action ="" method ="Post" name ="form2" >
< table width ="350px" height ="200px" cellspacing ="0" cellpadding ="0" align ="center" border ="0" bgcolor ="#c0c0c0" >
< tr >< td colspan ="3" > </ td ></ tr >
< tr >< td colspan ="3" >< font color ="red" id ="check" ></ font ></ td ></ tr >
< tr >< td colspan ="3" align ="center" > 用户注册 </ td ></ tr >
< tr >< td align ="right" > 用户名: </ td >< td >< input type ="text" name ="name" maxlength ="20" size ="15" id ="name" />< font color ="red" > * </ font ></ td >< td >< a onclick ="checkUsername()" class ="btn_grey" > [检查用户名] </ a ></ td ></ tr >
< tr >< td align ="right" > 密 码: </ td >< td >< input type ="password" name ="pass" maxlength ="20" size ="15" onKeyPress ="registerHandler(event)" />< font color ="red" > * </ font ></ td ></ tr >
< tr >< td colspan ="3" align ="center" >< input type ="button" value ="提交" class ="btn_grey" onclick ="addUser()" /> < input type ="reset" value ="重置" class ="btn_grey" /></ td ></ tr >
< tr >< td align ="center" colspan ="3" >< a href ="/chat/login.jsp" > 用户登录 </ a ></ td ></ tr >
</ table >
</ form >
</ body >
</ html >
(3)regSuccess.jsp
<! 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=UTF-8" >
< link href ="CSS/style.css" rel ="stylesheet" type ="text/css" >
< script language ="JavaScript" src ="js/Chat.js" type ="text/javascript" ></ script >
< script language ="JavaScript" src ="js/prototype.js" type ="text/javascript" ></ script >
< title > register success </ title >
</ head >
< body onload ="toLogin()" >
< br >
< br >
< b > 恭喜你,注册成功,本页面将在3秒钟后返回登录页面。 < a href ="/chat/login.jsp" >< font size ="5" > 点击返回 </ font ></ a ></ b >
</ body >
</ html >
(4)chat.jsp
<% ... @ taglib uri="/WEB-INF/app.tld" prefix="app" %>
<! 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=UTF-8" >
< link href ="CSS/style.css" rel ="stylesheet" type ="text/css" >
< script type ="text/javascript" language ="JavaScript" src ="js/Chat.js" ></ script >
< script type ="text/javascript" language ="JavaScript" src ="js/prototype.js" ></ script >
< title > 聊天室 </ title >
</ head >
< body onLoad ="sendEmptyMsg()" >
< form action ="" method ="Post" name ="chatForm" >
< table width ="400px" height ="400px" cellspacing ="0" cellpadding ="0" align ="center" border ="1px" bgcolor ="#c0c0c0" >
< tr >< td colspan ="2" height ="1" >< app:ValidateSessionTag /></ td ></ tr >
< tr >< td align ="center" height ="20" colspan ="3" valign ="top" bgcolor ="#ff80ff" > 南洋303成人聊天室 </ td ></ tr >
< tr >< td >< textarea name ="area" rows ="20" cols ="50" id ="area" readOnly ></ textarea ></ td ></ tr >
< tr >< td >< input type ="text" name ="msg" maxlength ="50" size ="50" onKeyPress ="msgHandler(event)" /> < input type ="button" value ="发送" class ="btn_grey" onclick ="sendMsg()" /> < input type ="button" value ="退出聊天室" class ="btn_grey" onclick ="leaveRoom()" /></ td ></ tr >
</ table >
</ form >
</ body >
</ html >
3.struts框架中的action
(1)LoginAction.java
import javax.servlet.http. * ;
import org.apache.struts.action. * ;
import form. * ;
import service. * ;
import java.io. * ;
public class LoginAction extends Action ... {
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception...{
LoginForm dyForm=(LoginForm)form;
String name=null;
String pass=null;
name=dyForm.getName();
pass=dyForm.getPass();
ChatService cs=null;
cs=ChatService.instance();
boolean ok=cs.validLogin(name, pass);
if(ok)...{
HttpSession session=request.getSession();
session.setAttribute("user", name);
response.setContentType("text/xml;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out=response.getWriter();
out.println("<res>"+"ok"+"</res>");
out.close();
return mapping.findForward("null");
}else...{
response.setContentType("text/xml;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out=response.getWriter();
out.println("<res>"+"对不起,用户名或密码有错,登录失败!"+"</res>");
out.close();
return mapping.findForward(null);
}
}
}
(2)AddUserAction.java
import javax.servlet.http. * ;
import org.apache.struts.action. * ;
import service. * ;
import xml. * ;
public class AddUserAction extends Action ... {
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception...{
String name=null;
String pass=null;
DynaActionForm dy=(DynaActionForm)form;
name=(String)dy.get("name");
pass=(String)dy.get("pass");
boolean ok=false;
ok=ChatService.instance().addUser(name, pass);
CheckUsernameXml.addUserXml(response, ok);
return mapping.findForward(null);
}
}
(3)CheckUsername.java
import javax.servlet.http. * ;
import org.apache.struts.action. * ;
import service. * ;
import xml. * ;
public class CheckUsername extends Action ... {
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception...{
String name=null;
name=request.getParameter("name");
boolean has=false;
has=ChatService.instance().checkUsername(name);
CheckUsernameXml.responseXml(response, has);
/** *//**response.setContentType("text/xml;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out=response.getWriter();
if(has){
out.println("<check>"+"该用户名可以使用。"+"</check>");
}else{
out.println("<check>"+"该用户名已经存在,请重新换一个用户名。"+"</check>");
}
out.close();**/
return mapping.findForward(null);
}
}
(4).ChatAction.java
import javax.servlet.http. * ;
import org.apache.struts.action. * ;
import service. * ;
import xml. * ;
public class ChatAction extends Action ... {
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception...{
String user=null;
String msg=null;
String msgs=null;
msg=(String)request.getParameter("msg");
if(msg==null)...{
msgs=ChatService.instance().getMsg();
CheckUsernameXml.showMsgXml(response, msgs);
return mapping.findForward(null);
}
HttpSession session=request.getSession();
user=(String)session.getAttribute("user");
ChatService.instance().addMsg(user, msg);
msgs=ChatService.instance().getMsg();
CheckUsernameXml.showMsgXml(response, msgs);
return mapping.findForward(null);
}
}
(5).LeaveAction.java
import javax.servlet.http. * ;
import org.apache.struts.action. * ;
public class LeaveAction extends Action ... {
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception...{
HttpSession session=request.getSession();
session.invalidate();
return mapping.findForward("success");
}
}
4.service层
(1)ChatService.java
import java.io. * ;
import java.util. * ;
public class ChatService ... {
/** *//**
* 该组件为单态模式
*/
private static ChatService cs;
private Properties userList;
private LinkedList<String> chatMsg;
private ChatService()...{}
public static ChatService instance()...{
if(cs==null)...{
cs=new ChatService();
}
return cs;
}
private Properties loadUser()throws IOException...{
if(userList==null)...{
File f=new File("userFile.properties");
if(!f.exists())...{
f.createNewFile();
}
userList=new Properties();
userList.load(new FileInputStream(f));
}
return userList;
}
private boolean saveUserList()throws IOException...{
if(userList==null)
return false;
userList.store(new FileOutputStream("userFile.properties"), "userList");
return true;
}
/** *//**
* 验证用户名和密码是否可以登录
* @param user
* @param pass
* @return
* @throws IOException
*/
public boolean validLogin(String user,String pass)throws IOException...{
if(loadUser().getProperty(user)==null)...{
return false;
}
if(loadUser().getProperty(user).equals(pass))...{
return true;
}
return false;
}
/** *//**
* 用户注册
* @param name
* @param pass
* @return
* @throws Exception
*/
public boolean addUser(String name,String pass)throws Exception...{
if(userList==null)...{
userList=loadUser();
}
if(userList.containsKey(name))...{
return false;
}
userList.setProperty(name, pass);
saveUserList();
return true;
}
/** *//**
* 检查用户名是否已存在
* @param name
* @return
* @throws Exception
*/
public boolean checkUsername(String name)throws Exception...{
if(userList==null)...{
userList=loadUser();
}
if(userList.containsKey(name))...{
return false;
}
return true;
}
/** *//**
* 获取所有聊天信息
* @return
*/
public String getMsg()...{
if(chatMsg==null)...{
chatMsg=new LinkedList<String>();
return "";
}
String result="";
for(String tmp:chatMsg)...{
result+=tmp+" ";
}
return result;
}
/** *//**
* 添加用户聊天信息
* @param user
* @param msg
*/
public void addMsg(String user,String msg)...{
if(chatMsg==null)...{
chatMsg=new LinkedList<String>();
}
if(chatMsg.size()>40)...{
chatMsg.removeFirst();
}
chatMsg.add(user+"说:"+msg);
}
}
5.Util包,几个帮助类
(1)SetCharacterEncodingFilter.java
import javax.servlet. * ;
import java.io.IOException;
public class SetCharacterEncodingFilter implements Filter ... {
public void destroy()...{}
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException...{
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig)throws ServletException...{
}
}
(2)一个验证用户是否登录的DisplayTag----ValidateSessionTag.java
import javax.servlet.http. * ;
import javax.servlet.jsp. * ;
import javax.servlet.jsp.tagext. * ;
public class ValidateSessionTag extends TagSupport ... {
public static final long serialVersionUID=-1814239825517340645L;
public int doStartTag()throws JspException...{
return SKIP_BODY;
}
public int doEndTag()throws JspException...{
HttpSession session=pageContext.getSession();
String user=(String)session.getAttribute("user");
if(user==null)...{
try...{
pageContext.forward("/login.jsp");
}catch(Exception e)...{
e.printStackTrace();
}
}
return super.doEndTag();
}
}
6.生成返回客户端xml数据的工具类包------xml
(1)BaseXml.java
import java.io.PrintWriter;
import javax.servlet.http. * ;
public class BaseXml ... {
public static PrintWriter getWriter(HttpServletResponse response)throws Exception...{
response.setContentType("text/xml;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out=response.getWriter();
return out;
}
}
2.CheckUsernameXml.java(名字是随意取的哈)
import javax.servlet.http. * ;
import java.io. * ;
public class CheckUsernameXml extends BaseXml ... {
public static void responseXml(HttpServletResponse response,boolean has)throws Exception...{
PrintWriter out=getWriter(response);
if(has)...{
out.println("<check>"+"该用户名可以使用。"+"</check>");
}else...{
out.println("<check>"+"该用户名已经存在,请重新换一个用户名。"+"</check>");
}
out.close();
}
public static void addUserXml(HttpServletResponse response,boolean ok)throws Exception...{
PrintWriter out=getWriter(response);
if(ok)...{
out.println("<ok>"+"ok"+"</ok>");
}else...{
out.println("<ok>"+"该用户名已经存在。"+"</ok>");
}
out.close();
}
public static void showMsgXml(HttpServletResponse response,String msgs)throws Exception...{
PrintWriter out=getWriter(response);
out.println("<msg>"+msgs+"</msg>");
out.close();
}
}
7.xml.配置文件
(1).web.xml
<! DOCTYPE web - app PUBLIC
' -//Sun Microsystems, Inc.//DTD Web Application 2.3//EN '
' http://java.sun.com/j2ee/dtds/web-app_2_3.dtd ' >
< web - app >
< servlet >
< servlet - name > action </ servlet - name >
< servlet - class > org.apache.struts.action.ActionServlet </ servlet - class >
< init - param >
< param - name > config </ param - name >
< param - value >/ WEB - INF / struts - config.xml </ param - value >
</ init - param >
< load - on - startup > 2 </ load - on - startup >
</ servlet >
< servlet - mapping >
< servlet - name > action </ servlet - name >
< url - pattern >* . do </ url - pattern >
</ servlet - mapping >
< filter >
< filter - name > setCharacterEncodingFilter </ filter - name >
< filter - class > util.SetCharacterEncodingFilter </ filter - class >
</ filter >
< filter - mapping >
< filter - name > setCharacterEncodingFilter </ filter - name >
< url - pattern > /**/ /*</url-pattern>
</filter-mapping>
<tag-lib>
<taglib-uri>/WEB-INF/app.tld</taglib-uri>
<taglib-location>/WEB-INF/app.tld</taglib-location>
</tag-lib>
</web-app>
(2).struts-config.xml
<! DOCTYPE struts - config PUBLIC " -//Apache Software Foundation//DTD Struts Configuration 1.2//EN " " struts-config_1_2.dtd " >
< struts - config >
< form - beans >
< form - bean name = " loginForm " type = " form.LoginForm " ></ form - bean >
< form - bean name = " addUserForm " type = " org.apache.struts.action.DynaActionForm " >
< form - property name = " name " type = " java.lang.String " ></ form - property >
< form - property name = " pass " type = " java.lang.String " ></ form - property >
</ form - bean >
</ form - beans >
< action - mappings >
<!-- 用户登录 -->
< action path = " /login "
type = " action.LoginAction "
name = " loginForm "
scope = " request "
>
< forward name = " success " path = " /chat/chat.jsp " ></ forward >
< forward name = " false " path = " /login.jsp " ></ forward >
</ action >
<!-- 检查用户名是否可用 -->
< action path = " /checkUsername "
type = " action.CheckUsername "
>
< forward name = " success " path = " /chat/register.jsp " ></ forward >
</ action >
<!-- 注册新用户 -->
< action path = " /addUser "
type = " action.AddUserAction "
name = " addUserForm "
scope = " request "
>
< forward name = " success " path = " /chat/register.jsp " ></ forward >
</ action >
<!-- 刷新聊天记录 -->
< action path = " /addMsg "
type = " action.ChatAction "
>
< forward name = " success " path = " /chat/chat.jsp " ></ forward >
</ action >
<!-- 退出聊天室 -->
< action path = " /leaveRoom "
type = " action.LeaveAction "
>
< forward name = " success " path = " /chat/login.jsp " ></ forward >
</ action >
</ action - mappings >
</ struts - config >
(3)app.tld(客户化标签库)
<! DOCTYPE taglib
PUBLIC " -//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN "
" http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd " >
< taglib >
< tlib - version > 1.0 </ tlib - version >
< jsp - version > 1.2 </ jsp - version >
< short - name > tagSample </ short - name >
< uri >/ tagSample </ uri >
< description > sphinx app tags </ description >
< tag >
< name > ValidateSessionTag </ name >
< tag - class > util.ValidateSessionTag </ tag - class >
< body - content > empty </ body - content >
< display - name ></ display - name >
< small - icon ></ small - icon >
< large - icon ></ large - icon >
< description ></ description >
< example ></ example >
</ tag >
</ taglib >
8.对于struts的jar和tld等的配置请参看其它相关的资料。