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

来源:互联网 发布:mac手绘板没有压感 编辑:程序博客网 时间:2024/06/10 07:44

<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 blocke.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一个实例,解决钱程安全问题。


希望遇到这个问题的朋友能迅速解决,不要像我这样浪费时间了!