在上一篇中已经实现了基本的数据库写入操作,但是实际项目中,是不允许如此不设防注册的,比如说用户名要唯一,身份证号码要合法,各种字段必须要填,两次密码要一致等等,那么有哪些方式可以进行这种验证呢,客户端验证和服务端验证相关答案有很多,这里就不一一列举了,这里只写我认为比较好用的方式,有的项目同时需要客户端验证和服务端验证,那就由项目具体的需求决定。

还用上一篇的jsp进行检验,使用技术就是jQuery框架的validate插件,所需要的文件可以在/Files/DyEnigma/验证.rar下载

在webroot下面建立一个文件夹js,然后把这4个文件放进去,在index.jsp页面引用这4个js文件

1 <head>
2         <title>简单的注册页面</title>
3         <script type="text/javascript"src="js/jquery-1.6.1.js"></script>
4         <script type="text/javascript"src="js/jquery.validate.js"></script>
5         <script type="text/javascript"src="js/jquery.metadata.js"></script>
6         <script type="text/javascript"src="js/validate_ex.js"></script>
7     </head>

这里需要说明的是,jquery-1.6.1.js必须放在第一位,原因详见【待填】,另外还有个问题,有时候为了安全起见,我们把jsp文件都放在了WEB-INF文件夹里面,如果使用相对路径,它会找不到放在外面的文件,比如说css、js、图片之类,这时候的解决办法就是使用绝对路径,如:/DyEngima/js/jquery-1.6.1.js。如果觉得判断很麻烦,全部使用绝对路径就对了。

然后建立自己的js文件,在js文件夹中新建js,命名为main.js,并在index.jsp文件中导入此js,并对各字段写入框架验证编码,index.jsp最终代码如下

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%@ taglib uri="/struts-tags" prefix="s"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5     <head>
 6         <title>简单的注册页面</title>
 7         <script type="text/javascript" src="js/jquery-1.6.1.js"></script>
 8         <script type="text/javascript" src="js/jquery.validate.js"></script>
 9         <script type="text/javascript" src="js/jquery.metadata.js"></script>
10         <script type="text/javascript" src="js/validate_ex.js"></script>
11         <script type="text/javascript" src="js/main.js"></script>
12     </head>
13     <body>
14         <s:form action="op_insert" namespace="/user" method="post"
15             id="regForm">
16             <table class="mytable">
17                 <tr>
18                     <td>
19                         <label for="name">
20                             *帐号:
21                         </label>
22                     </td>
23                     <td>
24                         <s:textfield id="name" name="user.userName" value=""
25                             cssClass="required" />
26                         <p>
27                             用户名为3-16个字符,可以为数字、字母、下划线
28                         </p>
29                     </td>
30                 </tr>
31                 <tr>
32                     <td>
33                         <label for="password">
34                             *密码:
35                         </label>
36                     </td>
37                     <td>
38                         <s:password id="password" name="user.userPassword" value=""
39                             cssClass="{required:true,rangelength:[6,16]}" />
40                         <p>
41                             最小长度:6 最大长度:16
42                         </p>
43                     </td>
44                 </tr>
45                 <tr>
46                     <td>
47                         <label for="repassword">
48                             *确认密码:
49                         </label>
50                     </td>
51                     <td>
52                         <s:password id="repassword" value="" name="repassword"
53                             cssClass="{required:true,rangelength:[6,16],equalTo:'#password',messages:{equalTo:'两次密码输入不一致.'}}" />
54                     </td>
55                 </tr>
56                 <tr>
57                     <td>
58                         <label for="true">
59                             *真实姓名:
60                         </label>
61                     </td>
62                     <td>
63                         <s:textfield id="true" name="user.trueName" value=""
64                             cssClass="required" />
65                     </td>
66                 </tr>
67                 <tr>
68                     <td>
69                         <label for="peopleId">
70                             *身份证号:
71                         </label>
72                     </td>
73                     <td>
74                         <s:textfield id="peopleId" name="user.peopleId" value=""
75                             cssClass="{required:true,isIdCardNo:true}" />
76                         <p>
77                             请输入18位的身份证号码
78                         </p>
79                     </td>
80                 </tr>
81                 <tr>
82                     <td>
83                         &nbsp;
84                     </td>
85                     <td>
86                         <s:submit value="添加" />
87                         <s:reset value="重置" />
88                     </td>
89                 </tr>
90             </table>
91         </s:form>
92     </body>
93 </html>
94 

注意各字段中cssClass部分,这些就是根据jQuery-validate验证插件完成的配置,详细请见【待填】;这里简单说明一下,required标记该输入框不能为空,rangelength标记该输入框的长度范围限制,equalTo:'#password'检验这个输入框数值和id为password的输入框数值是否一致,message是如果equalTo检验结果为否的情况下,给用户的提示信息,isIdCardNo:true检验该输入框输入的数值是否是个身份证号码,这些都是jsp页面的检验,另外还有用户名唯一,身份证号码唯一检验,请看main.js。
 1 $(function() {
 2     
 3     // 表单验证,用户名、身份证
 4     $("#regForm").validate({
 5                 focusCleanup : true,
 6                 rules : {
 7                     'user.userName' : {
 8                         maxlength : 16,
 9                         minlength : 3,
10                         userName : true,
11                         remote : {
12                             url : "/DyEngima/user/ck_checkUser.do",
13                             type : "post",
14                             data : {
15                                 'user.userName' : function() {
16                                     return encodeURIComponent($("#name").val());
17                                 }
18                             }
19                         }
20                     },
21                     'user.peopleId' : {
22                         remote : {
23                             url : "/DyEngima/user/ck_checkPeopleId.do",
24                             type : "post",
25                             data : {
26                                 'user.peopleId' : function() {
27                                     return encodeURIComponent($("#peopleId").val());
28                                 }
29                             }
30                         }
31                     }
32                 },
33                 messages : {
34                     'user.userName' : {
35                         remote : "该用户名已存在,请使用其他的用户名."
36                     },
37                     'user.peopleId' : {
38                         remote : "身份证号码已经存在."
39                     },
40                     low : ""
41                 },
42                 errorPlacement : function(error, element) {
43                     if (element.is(":radio"))
44                         error.appendTo(element.parent());
45                     else if (element.is(":checkbox"))
46                         error.appendTo(element.parent());
47                     else if (element.is("input[name=captcha]"))
48                         error.appendTo(element.parent());
49                     else
50                         error.insertAfter(element);
51                 },
52                 success : function(label) {
53                     label.html("&nbsp;").addClass("right");
54                 }
55             });
56 
57     // 表单重置
58     $("input:reset").click(function() {
59                 validate.resetForm();
60             });
61 }); 

新建一个action,命名为CheckAction.java。在cn.dy.dao包内的UserDao.java接口添加 public List<User> check(String username, String peopleId); 。

在cn.dy.dao.impl包内UserDaoBean.java类实现这个方法,这里要说明的是,不要使用“+”来连接查询字符串,第一不好维护,容易出错;第二,有被sql注入风险;而用"?"连接又会照成序号对应不上,而且当一个字段反复出现的话,就会一个一个都要列举出来,这里采用占位别名的方式处理。如果对SQL不熟练,可以使用别的方法:【待填】

 1     @SuppressWarnings("unchecked")
 2     @Override
 3     @Transactional(propagation = Propagation.NOT_SUPPORTED)
 4     public List<User> check(String username, String peopleId) {
 5         String hql = "from User where username=:name or peopleId=:PID";
 6         Query q = factory.getCurrentSession().createQuery(hql);
 7         q.setString("name", username);
 8         q.setString("PID", peopleId);
 9         List list = q.list();
10        return list;
11     }

在cn.dy.service包内UserService.java接口添加 public boolean check(String username, String peopleId); 这里的返回值,就和dao中的那个接口不一样。
在cn.dy.service.impl包内的UserServiceBean.java类中实现这个方法(注意比较代码,这就是业务层和数据层的区别),注意import相关包,错误地方按F2可以出现提示。

1     @Override
2     public boolean check(String username,String peopleId) {
3         // 业务判断,看将要注册的帐号名或者身份证号码,是否已经存在
4         if (userDao.check(username,peopleId).isEmpty()) {
5             return true;
6         } else {
7             return false;
8         }
9     }

相关方法已经实现,CheckAction.java里面直接调用,代码如下

 1 package cn.dy.action;
 2 
 3 import java.io.InputStream;
 4 import java.io.StringBufferInputStream;
 5 import java.io.UnsupportedEncodingException;
 6 import javax.annotation.Resource;
 7 import org.springframework.stereotype.Controller;
 8 import cn.dy.bean.User;
 9 import cn.dy.service.UserService;
10 import com.opensymphony.xwork2.ActionSupport;
11 
12 @SuppressWarnings("deprecation")
13 @Controller
14 public class CheckAction extends ActionSupport {
15 
16     private static final long serialVersionUID = -859896811239454253L;
17     @Resource
18     UserService userService;
19 
20     private InputStream inputStream;
21     private User user;
22 
23     public User getUser() {
24         return user;
25     }
26 
27     public void setUser(User user) {
28         this.user = user;
29     }
30 
31     public InputStream getInputStream() {
32         return inputStream;
33     }
34 
35     public String checkUser() {
36         String name = user.getUserName();
37         try {
38             name = java.net.URLDecoder.decode(name, "utf-8");
39         } catch (UnsupportedEncodingException e) {
40             e.printStackTrace();
41         }
42         String pass = "false";
43         if (userService.check(name, "")) {
44             pass = "true";
45         }
46         inputStream = new StringBufferInputStream(pass);
47         return "check";
48     }
49 
50     public String checkPeopleId() {
51         String peopleId = user.getPeopleId();
52         String pass = "false";
53         if (userService.check("", peopleId)) {
54             pass = "true";
55         }
56         inputStream = new StringBufferInputStream(pass);
57         return "check";
58     }
59 }
60 

struts.xml文件里面新添加的配置

1 <action name="ck_*" class="checkAction" method="{1}">
2             <result name="input">/index.jsp</result>
3             <result name="check" type="stream">
4                 <param name="contentType">text/html</param>
5                 <param name="inputName">inputStream</param>
6             </result>
7         </action>

注意第二个result的格式,必须这样声明才能在前台页面获取返回值。

好了,让我们检验一下。噢,出现一个问题,可以进行长度、是否为空、是否是身份证校验,但是,不能判断用户名、身份证是否存在,原来是js文件中的跳转路径的问题,在这里是.do结尾的,而struts2中默认是.action结尾,我们在struts.xml文件中加上这个一句:<constant name="struts.action.extension" value="do" />;设置默认为.do结尾就好了,现在再看看吧,成功。如果出现乱码问题,请检查页面、js文件的编码是否为UTF-8。


      此文部分内容来源网络。如有侵犯您的版权问题,请来消息至电子邮件DyEngima&163.com(&换成@),经核实后会在文章内部标明来源。
转载请注明来源http://www.blogjava.net/DyEnigma/
签名:有能力、有担当、有情义的人才能称之为男人,而不是由性别决定。