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

3 篇文章 0 订阅
3 篇文章 0 订阅
在构建BBS论坛时,遇到使用jQuery+Ajax验证用户名存在的问题,Ajax请求未按预期执行Struts2 Action的验证方法,而是直接显示Struts2的字段错误信息。原因是Struts2 action在Spring中默认为单例模式,导致验证信息重复。解决办法是将Spring中的action配置为多例模式,避免缓存导致的问题。
摘要由CSDN通过智能技术生成

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


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





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值