您的位置:首页 > Web前端 > JQuery

学习struts2建bbs总结五:使用jquery+ajax验证用户名是否存在以及struts效验信息不断重复的问题

2012-08-16 15:12 1216 查看
<FORM name="regForm" onSubmit="return check()" action="register.action" method="post">
<br/>用 户 名
<INPUT id="name" class="input" tabIndex="1"  type="text" maxLength="20" size="35" name="userName" onBlur="javascript:existU()"/>
*
<div id="exsitUser" style="color:#ff0000"></div>
<br/>密    码
<INPUT class="input" tabIndex="2" type="password" maxLength="20" size="40" name="pwd"/>
*<br/>重复密码
<INPUT class="input" tabIndex="3" type="password" maxLength="20" size="40" name="uPass1">
*<br/>性别
女<input type="radio" name="sex" value="1">
男<input type="radio" name="sex" value="2" checked="checked" />
<br/>请选择头像 <br/>
<img src="image/head/1.gif"/><input type="radio" name="picFileName" value="1.gif" checked="checked">
<img src="image/head/2.gif"/><input type="radio" name="picFileName" value="2.gif">
<img src="image/head/3.gif"/><input type="radio" name="picFileName" value="3.gif">
<img src="image/head/4.gif"/><input type="radio" name="picFileName" value="4.gif">
<img src="image/head/5.gif"/><input type="radio" name="picFileName" value="5.gif">
<BR/>
<img src="image/head/6.gif"/><input type="radio" name="picFileName" value="6.gif">
<img src="image/head/7.gif"/><input type="radio" name="picFileName" value="7.gif">
<img src="image/head/8.gif"/><input type="radio" name="picFileName" value="8.gif">
<img src="image/head/9.gif"/><input type="radio" name="picFileName" value="9.gif">
<img src="image/head/10.gif"/><input type="radio" name="picFileName" value="10.gif">
<BR/>
<img src="image/head/11.gif"/><input type="radio" name="picFileName" value="11.gif">
<img src="image/head/12.gif"/><input type="radio" name="picFileName" value="12.gif">
<img src="image/head/13.gif"/><input type="radio" name="picFileName" value="13.gif">
<img src="image/head/14.gif"/><input type="radio" name="picFileName" value="14.gif">
<img src="image/head/15.gif"/><input type="radio" name="picFileName" value="15.gif">
<br/>
email:<input type="text" name="email"> <br/>
密码提示问题:<input type="text" name="question"><br/>
问题答案:<input type="text" name="answer"> <br/>
昵称:<input type="text" name="nickName"> <br/>
签名:<input type="text" name="signDetail"> <br/>
自我简介:<input type="text" name="brief"> <br/>
时区:<input type="text" name="timeZone"> <br/>
身高:<input type="text" name="height"> <br/>
体重:<input type="text" name="weight"> <br/>
你最喜欢的人:<input type="text" name="favourPeople"> <br/>
你最喜欢的音乐:<input type="text" name="favourMusic"> <br/>
你最喜欢的电影:<input type="text" name="favourMovie"> <br/>
qq:<input type="text" name="oicqNo"> <br/>

<INPUT class="btn" tabIndex="4" type="submit" value="注 册">
</FORM>


上面是我的注册界面,判断用户名是否已经存在并打印出提示信息。

其中ajax相关js代码如下:

function existU()
{
var nm = document.regForm.userName.value;
var url='register_Ishave.action?userName=';
url=url+nm+"&sid=register&li="+Math.random();
xmlhttp=GetXmlHttp();
xmlhttp.onreadystatechange=StateChange;
xmlhttp.open("post",url,true);
xmlhttp.send();

}

function GetXmlHttp()
{
//1.创建XMLHttpRequest对象
//这是XMLHttpReuquest对象无部使用中最复杂的一步
//需要针对IE和其他类型的浏览器建立这个对象的不同方式写不同的代码

if (window.XMLHttpRequest) {
//针对FireFox,Mozillar,Opera,Safari,IE7,IE8
xmlhttp = new XMLHttpRequest();
//针对某些特定版本的mozillar浏览器的BUG进行修正
if (xmlhttp.overrideMimeType) {
xmlhttp.overrideMimeType("text/xml");
}
} else if (window.ActiveXObject) {
//针对IE6,IE5.5,IE5
//两个可以用于创建XMLHTTPRequest对象的控件名称,保存在一个js的数组中
//排在前面的版本较新
var activexName = ["MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
for (var i = 0; i < activexName.length; i++) {
try{
//取出一个控件名进行创建,如果创建成功就终止循环
//如果创建失败,回抛出异常,然后可以继续循环,继续尝试创建
xmlhttp = new ActiveXObject(activexName[i]);
break;
} catch(e){
}
}
}
//确认XMLHTtpRequest对象创建成功
if (!xmlhttp) {
alert("XMLHttpRequest对象创建失败!!");
return;
} else {
// alert(xmlhttp.readyState);
}

return xmlhttp;
}

function StateChange()
{
if(xmlhttp.readyState==4&&xmlhttp.status==200)
{
//alert(strlen(xmlhttp.responseText));
//if(strlen(xmlhttp.responseText)<100){
document.getElementById("exsitUser").innerHTML=xmlhttp.responseText;
}
//}
}


在registerAciton里有方法:

//判断用户名是否存在,如果不存在才可以注册。
public void Ishave() {
HttpServletResponse response = ServletActionContext.getResponse();
//设置字符集
response.setContentType("text/plain");//设置输出为文字流
response.setCharacterEncoding("UTF-8");
PrintWriter out;
setMsg_user("");
try {
out = response.getWriter();
setMsg_user(userService.IshaveUsername(userName));
out.println(msg_user);
//userName=null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


当年ajax学的很少,于是用了那时的一个js文件如上,当时是写一个php程序,不过现在看起来略微改动也可以使用。但没想到几年后的今天,ie8,ie9均无法正常运行上面的代码。真个头大。近来学习struts,spring文章,也了解到那样写ajax代码实在不值得啊,于是也学了学jquery,算是个简单的入门吧。

首先下载jquery.js导入,然后直接重写existU()方法,这可简单得太多了!!!

function existU()
{
//var nm = document.regForm.userName.value;
//var url='register_Ishave.action?userName=';
//url=url+nm+"&sid=register&li="+Math.random();
//xmlhttp=GetXmlHttp();
//xmlhttp.onreadystatechange=StateChange;
//xmlhttp.open("post",url,true);
//xmlhttp.send();
if($('#name').val() == ''){
$('#exsitUser').html("<span style='color:red;'>不能为空</span>");
}
else{
$.post('register_Ishave.action',{userName:$('#name').val(),timestamp:new Date().getTime()},function(msg_user){
$('#exsitUser').html("<span style='color:red;'>"+msg_user+"</span>");
});
}
}


效果一样,这个在ie8、谷歌浏览器也可以正常运行。代码还方便了这么多。





然而,我在做bbs过程中,遇到的一大头疼问题便是由此而来。我为这个注册页面定义了一个xml效验文件RegisterAction-register-validation.xml,如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.3//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<validators>
<field name="userName">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空!</message>
</field-validator>
</field>
<field name="pwd">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>密码不能为空!</message>
</field-validator>
<field-validator type="stringlength">
<param name="trim">true</param>
<param name="maxLength">20</param>
<param name="minLength">4</param>
<message>密码应该在4--20位!</message>
</field-validator>
</field>

<field name="email">
<field-validator type="email">
<param name="fieldName">email</param>
<message>电子邮件地址无效!</message>
</field-validator>
</field>
</validators>


如果不点击注册页面的注册按钮,也就是没有执行效验之前,前面的ajax验证用户名便一切正常。可是当我定义了上面的这个效验文件后,噩梦来了......

当第一次效验不通过,页面会打印出错误信息(我在jsp添加了<s:fielderror/>)。其中action配置如下:

<action name="register_*" class="registerAction" method="{1}">
<result name="success" type="chain">post_getBoards</result>
<result name="error">/error.jsp</result>
<result name="input">/register.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
打印出错误信息后,根据上面的配置,仍然显示register.jsp,可是当我再次输入用户名密码(输入错误格式),此时怪异问题出现!!

此时输入用户名后,ajax里的

$.post('register_Ishave.action',{userName:$('#name').val(),timestamp:new Date().getTime()}
这句代码已经不执行了,也就是说此时无法进入register.action的Ishave()方法,直接打印出嵌套的jsp页面,而且在效验过程中,发现上一次的效验信息没未消失,反而在之前的效验信息下增加了一条,如此不断重复的显示,此外,此时哪怕输入正确的用户名密码电子邮件,也已经无法注册了,程序几乎等于死了........如图:



(上面当我输入用户名后,本来应该按js执行进入action执行验证用户名的方法并返回结果的,可是我调试过程中发现并未进入action,而且还直接打印出红色文字,这个红色文字是我register.jsp的信息。)

我在网上不断发帖问人,不断看文章,大概心不诚啊均无结果。今日看到有高手提前struts2为有状态的,说每次action均会新建一个,而spring是以单例模式执行,所以不断会在map中不断新增原来的action信息,而导致重复,错误信息还在,自然也就无法执行响应的action了。

终于找到解决办法,说起来就是一句话,就是在spring中注册的action默认都是单例模式,需要改为多例模式,如下:

<bean id="registerAction" class="pengbbs.controller.RegisterAction" scope="prototype"
abstract="false" lazy-init="default" autowire="default"
p:userService-ref="userService">
</bean>


上面增加了scope="prototype"后,一切正常了!!一般而言,dao以及service、拦截器等不涉及与前台的数据交互,一般就是单例模式,singleton,而action需要定义多例模式,多例模式每次都会new一个实例,解决钱程安全问题。

希望遇到这个问题的朋友能迅速解决,不要像我这样浪费时间了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: