说到AJAX,每个人都不会陌生,毕竟这两年它太流行了。然而,真正哪些地方需要AJAX,并不是每个人都能够把握得很好。使用AJAX可以开发豪华的基于浏览器的富客户端界面,然而其开发量的庞大和调试的艰难,让每一个程序员如同生活在地狱中一般。 < script src ="scripts/prototype.js" ></ script >
var ajax = new Ajax.Request(url, {method: " get " , onComplete:onResponse} );
function onSubmit() {
var url = " RegUser.do?method=submit " ; // 将表单数据添加到url中以便于使用GET传递到服务器 var inputs = userForm.all.tags( " input " ); for ( var i = 0 ; i < inputs.length; i ++ ) { url = url + " & " + inputs[i].name + " = " + inputs[i].value; // 设置表单为不可用状态 inputs[i].disabled = " true " ; } // 提示用户正在提交数据 $( " doing " ).style.pixelTop = document.body.scrollTop + 230 ; $( " doing " ).style.left = 250 ; $( " doing " ).style.display = " block " ; // 使用AJAX将数据传递到服务器,并接受服务器的回应 var ajax = new Ajax.Request(url, {method: " get " , onComplete:onResponse} ); }
问题二、服务器返回什么数据给AJAX对象? function onResponse(request) {
eval(request.responseText); } 问题三、AJAX让Validator框架走开? 在Struts中,有一个验证框架Validator,它可以很方便的完成对ActionForm的验证。但是一旦我们使用AJAX,Validator就派不上任何用场,因为只有在jsp文件中使用Struts的<html:form>系列标签,才能让Struts表我们的表单数据自动封装到ActionForm中,但是前文已经提过,我们的表单数据是通过url参数传递的,所以除非自己扩展Struts,否则我们跟Validator无缘。 于是,所有的验证代码我们必须得在服务器端自己编写,即要考虑周全,又要防止出错。幸好SpringSide提供的HibernateEntityDao<T>让我们在验证用户名和昵称是否重复时省了一大把劲。我的服务器端代码如下: // ?????û??获取用户提交的数据并验证?????
public ActionForward submit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { boolean success = true; String result = ""; User user = new User(); // 验证用户名????û??? String name = new String(request.getParameter("name").getBytes( "ISO-8859-1"), "GB2312"); user.setName(name); if (name == null || name.equals("")) { success = false; result += "name_err.innerHTML=‘用户名不能为空‘;"; } else if (!name.matches("^[A-Za-z0-9_]*$")) { success = false; result += "name_err.innerHTML=‘用户名只能包含字母、数字和下划线‘;"; } else if (name.length() > 20) { success = false; result += "name_err.innerHTML=‘用户名不能超过20个字符‘;"; } // 判断用户名是否重复 else if (userManager.isNotUnique(user, "name")) { success = false; result += "name_err.innerHTML=‘该用户名已经被注册‘;"; }else{ result += "name_err.innerHTML=‘‘;"; } // 验证昵称 String monicker = new String(request.getParameter("monicker").getBytes( "ISO-8859-1"), "GB2312"); user.setMonicker(monicker); if (monicker == null || monicker.equals("")) { success = false; result += "monicker_err.innerHTML=‘昵称不能为空‘;"; } else if (monicker.matches("^.*[~!@#$%^&*()-=+<>?/‘\";:]+.*$")) { success = false; result += "monicker_err.innerHTML=‘昵称不能包含特殊字符‘;"; } else if (monicker.length() > 15) { success = false; result += "monicker_err.innerHTML=‘昵称不能超过15个字符‘;"; }// 判断昵称是否重复 else if (userManager.isNotUnique(user, "monicker")) { success = false; result += "monicker_err.innerHTML=‘该用昵称已经被使用‘;"; }else{ result += "monicker_err.innerHTML=‘‘;"; } // 验证两次输入的密码是否匹配 String password = new String(request.getParameter("password").getBytes( "ISO-8859-1"), "GB2312"); user.setPassword(password); String password_again = new String(request.getParameter( "password_again").getBytes("ISO-8859-1"), "GB2312"); if (password == null || password.equals("")) { success = false; result += "password_err.innerHTML=‘密码不能为空‘;"; } else if (password_again == null || password_again.equals("")) { success = false; result += "password_err.innerHTML=‘确认密码不能为空‘;"; } else if (!password.equals(password_again)) { success = false; result += "password_err.innerHTML=‘两次输入的密码不匹配‘;"; }else{ result += "password_err.innerHTML=‘‘;"; } // 验证密码问题和问题答案,规则和昵称相同 String question = new String(request.getParameter("question").getBytes( "ISO-8859-1"), "GB2312"); user.setQuestion(question); if (question == null || question.equals("")) { success = false; result += "question_err.innerHTML=‘问题不能为空‘;"; } else if (question.matches("^.*[~!@#$%^&*()-=+<>?/‘\";:]+.*$")) { success = false; result += "question_err.innerHTML=‘问题不能包含特殊字符‘;"; } else if (question.length() > 15) { success = false; result += "question_err.innerHTML=‘问题不能超过15个字符‘;"; }else{ result += "question_err.innerHTML=‘‘;"; } String answer = new String(request.getParameter("answer").getBytes( "ISO-8859-1"), "GB2312"); user.setQuestion(question); if (answer == null || answer.equals("")) { success = false; result += "answer_err.innerHTML=‘答案不能为空‘;"; } else if (answer.matches("^.*[~!@#$%^&*()-=+<>?/‘\";:]+.*$")) { success = false; result += "answer_err.innerHTML=‘答案不能包含特殊字符‘;"; } else if (answer.length() > 15) { success = false; result += "answer_err.innerHTML=‘答案不能超过15个字符‘;"; }else{ result += "answer_err.innerHTML=‘‘;"; } // 验证email String email = new String(request.getParameter("email").getBytes( "ISO-8859-1"), "GB2312"); user.setEmail(email); if (email == null || email.equals("")) { success = false; result += "email_err.innerHTML=‘Email不能为空‘;"; } else if (!email.matches("^[a-zA-Z0-9]*@[a-zA-Z0-9]*$")) { success = false; result += "email_err.innerHTML=‘不是有效的电子邮箱‘;"; } else if (email.length() > 40) { success = false; result += "email_err.innerHTML=‘Email不能超过40个字符‘;"; }else{ result += "email_err.innerHTML=‘‘;"; } // 验证QQ号码 String qq = new String(request.getParameter("qq") .getBytes("ISO-8859-1"), "GB2312"); user.setQq(qq); if (qq == null || qq.equals("")) { success = false; result += "qq_err.innerHTML=‘QQ号码不能为空‘;"; } else if (!qq.matches("^\\d*$")) { success = false; result += "qq_err.innerHTML=‘不是有效的QQ号码‘;"; } else if (qq.length() > 12) { success = false; result += "qq_err.innerHTML=‘QQ号码不能超过12位‘;"; } else if (qq.length() < 5) { result += "qq_err.innerHTML=‘QQ号码不能少于5位‘;"; }else{ result += "qq_err.innerHTML=‘‘;"; } // 验证验证码 String validateImage = new String(request.getParameter("validateImage") .getBytes("ISO-8859-1"), "GB2312"); if (validateImage == null || validateImage.equals("") || !validateImage.equals(request.getSession().getAttribute( "validateString"))) { success = false; result += "validateImage_err.innerHTML=‘验证码输入错误。如看不清,点击图片更换‘;"; }else{ result += "validateImage_err.innerHTML=‘‘;"; } //如果验证不成功,则调用JavaScript的failed()函数,否则,调用sucess(); if(success == false){ result += "failed();"; response.setCharacterEncoding("GB2312"); response.getOutputStream().println(result); response.flushBuffer(); }else{ //如果验证成功,把数据写入数据库中,要防止重复提交 if(this.isTokenValid(request)){ userManager.save(user); this.resetToken(request); } response.setCharacterEncoding("GB2312"); response.getOutputStream().println("success();"); response.flushBuffer(); } return null; } 客户端的failed()和success()函数如下: function failed(){
//掩藏提示信息 $("doing").style.display="none"; //设置表单为可用状态 var inputs = userForm.all.tags("input"); for(var i=0; i < inputs.length; i++){ inputs[i].disabled = ""; } } function success(){ $("doing").style.display="block"; $("doing").style.color="#0000FF"; $("doing").innerHTML = "用户注册成功,将跳转到首页!"; //4秒钟跳到首页 setTimeout("location.href=‘welcome.do‘;",4000); } 问题四、中文乱码问题如何解决? 我想每个人在使用AJAX的时候肯定都遇到过中文乱码的问题,我也不例外,这个问题困扰我的时间也不短,后来我总算时把它搞清楚了:AJAX使用的是另外一个线程,所以它的字符编码是和页面无关的,也就是说,它总是用GB2312编码向服务器发送数据,并且总是把接受到的数据当GB2312来理解,这是由我们操作系统决定的,我们大陆的操作系统默认编码都应该是GB2312吧。因此,在接受数据的时候,我们少不了: String name = new String(request.getParameter("name").getBytes(
"ISO-8859-1"), "GB2312"); 而发送数据的时候,也少不了: response.setCharacterEncoding("GB2312");
response.getOutputStream().println(result); response.flushBuffer(); 除此之外,还有浏览器之间对象不兼容的问题,可见写一个AJAX应用到处都是陷阱。 从上面大家可以看出,对于用户注册,我全部使用的/RegUser.do来进行处理,它继承自SpringSide的StrutsAction,是DispatherAction的子类。它的配置如下: struts-config.xml的action-mappings节中: <action path="/RegUser" scope="request" parameter="method">
<forward name="agree" path="/RegUser_Agree.jsp"/> <forward name="apply" path="/RegUser_Apply.jsp"/> </action> action-servlet.xml: <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www./dtd/spring-beans-2.0.dtd"> <beans default-autowire="byName" default-lazy-init="true"> <!-- 按模块导入Spring Action Config--> <import resource="modules/spring-config-admin.xml"/> <!-- 简单应用直接在此定义Action <bean name="/user" class="org.springside.helloworld.web.UserAction"/> --> <bean name="/welcome" class="com.xkland.action.WelcomeAction"/> <bean name="/RegUser" class="com.xkland.action.RegUserAction"/> </beans> 而这个com.xkland.action.RegUserAction的完整代码如下,希望大家多提意见: package com.xkland.action;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; import org.springside.core.web.StrutsAction; import com.xkland.manager.UserManager; import com.xkland.util.ImageUtil; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import com.xkland.domain.User; public class RegUserAction extends StrutsAction { private ImageUtil imageUtil; private UserManager userManager; public void setUserManager(UserManager userManager) { this.userManager = userManager; } public void setImageUtil(ImageUtil imageUtil) { this.imageUtil = imageUtil; } // 重定向到会员注册协议页面?? public ActionForward agree(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { return mapping.findForward("agree"); } // 重定向到填写表单页面?? public ActionForward apply(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { // 使用Token防止重复提交 saveToken(request); return mapping.findForward("apply"); } // 构造验证图片?????? public ActionForward createValidateImage(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { BufferedImage image = imageUtil.createValidateImage(request .getSession()); response.setContentType("image/jpeg"); try { ImageIO.write(image, "jpeg", response.getOutputStream()); response.flushBuffer(); } catch (Exception e) { } return null; } //获取用户提交的数据并验证 public ActionForward submit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //上面已贴代码,此处省略 } } |
|