在上一篇中已經實現了基本的數據庫寫入操作,但是實際項目中,是不允許如此不設防注冊的,比如說用戶名要唯一,身份證號碼要合法,各種字段必須要填,兩次密碼要一致等等,那么有哪些方式可以進行這種驗證呢,客戶端驗證和服務端驗證相關答案有很多,這里就不一一列舉了,這里只寫我認為比較好用的方式,有的項目同時需要客戶端驗證和服務端驗證,那就由項目具體的需求決定。

還用上一篇的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.aygfsteel.com/DyEnigma/
簽名:有能力、有擔當、有情義的人才能稱之為男人,而不是由性別決定。