1、數據加密處理前端
這裏使用MD5加密處理,使用java中自帶加密工具類MessageDigest。java
該類有一個方法digest,該方法輸入參數是一個字符串返回值是一個長度爲16的字節數組。最關鍵的是須要將這個16位的字節數組轉換成爲32位的字符串,轉換方法是使用位移+與運算。將高四位移到低四位&0X0F獲得一個字符,直接使用該值&0X0F獲得一個字符,這樣一個8bit的字節就可以拆成2個字符。最終16Byte就可以轉換成爲32個字符。spring
1 package com.kdyzm.utils; 2 3 import java.security.MessageDigest; 4 5 public class DataUtils { 6 7 //TODO md5加密工具 8 public static synchronized String md5(String input){ 9 try { 10 StringBuffer sb=new StringBuffer(); 11 String arr[]={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; 12 MessageDigest messageDigest=MessageDigest.getInstance("MD5"); 13 byte []data=messageDigest.digest(input.getBytes()); 14 System.out.println(data.length); 15 for(byte temp:data){ 16 //高四位 17 sb.append(arr[(temp>>4)&0X0F]); 18 //低四位 19 sb.append(arr[temp&0X0F]); 20 } 21 return sb.toString(); 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 return ""; 26 } 27 }
2、登錄驗證數據庫
單獨寫一個Action對登錄進行驗證apache
1 package com.kdyzm.struts.action; 2 3 import java.util.Map; 4 5 import javax.annotation.Resource; 6 7 import org.apache.struts2.interceptor.SessionAware; 8 import org.springframework.context.annotation.Scope; 9 import org.springframework.stereotype.Controller; 10 11 import com.kdyzm.domain.User; 12 import com.kdyzm.service.RightService; 13 import com.kdyzm.service.RoleService; 14 import com.kdyzm.service.UserService; 15 import com.kdyzm.struts.action.base.BaseAction; 16 @Controller("loginAction") 17 @Scope("prototype") 18 public class LoginAction extends BaseAction<User> implements SessionAware{ 19 private static final long serialVersionUID = 879952397314349337L; 20 @Resource(name="userService") 21 private UserService userService; 22 private Map<String,Object>session; 23 @Resource(name="rightService") 24 private RightService rightService; 25 @Resource(name="roleService") 26 private RoleService roleService; 27 //驗證用戶名和密碼的方法 28 public String chekEmailAndPassword() throws Exception{ 29 User user=userService.checkEmailAndPassword(this.model); 30 if(user==null){ 31 addActionError("用戶名或者密碼錯誤!"); 32 System.out.println("用戶名或者密碼錯誤!"); 33 return "input"; 34 }else{ 35 //關於怎麼將Session直接注入Action中的方法是一個比較難的題目 36 System.out.println("用戶登錄成功!"); 37 //在登錄成功的時候計算權限碼 38 int maxPos=rightService.getMaxPost(); 39 user.setRightSum(new long[maxPos+1]); 40 if(user.isSuperAdmin()){ 41 user.setSuperAdmin(true); 42 }else{ 43 user.setSuperAdmin(false); 44 } 45 //TODO 必定要把計算權限總和的語句放在最後,不然一旦將roles置爲null,其它方法調用的時候就會出現空指針異常! 46 user.calculateRightSum(); 47 48 session.put("user", user); 49 } 50 return "toIndexPage"; 51 } 52 @Override 53 public void setSession(Map<String, Object> session) { 54 this.session=session; 55 } 56 57 }
技術點有:數組
1.獲取Session的方法:實現SessionAware接口session
2.若是登錄成功就將User對象保存到Session中去,若是登陸失敗,則須要在返回前端的時候進行提示app
addActionError("用戶名或者密碼錯誤!");
前端只須要使用struts2標籤進行顯示便可:dom
<s:actionerror/>
3.粗體部分先忽略,是權限控制部分的內容。jsp
3、登陸攔截器
使用登陸攔截器的做用是攔截沒有登錄的用戶訪問。
1.首先新建一個類繼承Interceptor,其中進行是否登錄的驗證。
package com.kdyzm.struts.interceptors; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import com.kdyzm.domain.User; import com.kdyzm.domain.security.Right; import com.kdyzm.struts.action.aware.UserAware; import com.kdyzm.utils.ValidateUtils; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.interceptor.Interceptor; /** * 只要請求了Action就會默認訪問該攔截器 * 登錄攔截器 * @author kdyzm * */ public class LoginInterceptor implements Interceptor{ private static final long serialVersionUID = 7321012192261008127L; @Override public void destroy() { System.out.println("登陸攔截器被銷燬!"); } @Override public void init() { System.out.println("登陸攔截器初始化!"); } @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println("被登陸攔截器攔截!"); Action action=(Action) invocation.getAction(); if(action instanceof LoginAction ||action instanceof RegisterAction){ System.out.println("即將進行登陸或者註冊,直接放行!"); return invocation.invoke(); } HttpServletRequest request=ServletActionContext.getRequest(); HttpSession session=request.getSession(); User user=(User) session.getAttribute("user"); if(user==null){ System.out.println("用戶未登陸,必須先登陸再訪問其餘資源!即將跳轉到登錄界面!"); return "toLoginPage"; }else{ System.out.println("用戶已經登錄,登陸攔截器已經放行!");return invocation.invoke(); } } }
2.相應的須要改變strus2的默認棧
1 <interceptors> 2 <interceptor name="loginInterceptor" class="com.kdyzm.struts.interceptors.LoginInterceptor"></interceptor> 3 <interceptor-stack name="surveyparkStack"> 4 <interceptor-ref name="loginInterceptor"></interceptor-ref> 5 <interceptor-ref name="defaultStack"></interceptor-ref> 6 </interceptor-stack> 7 </interceptors> 8 <!-- 定義默認棧 --> 9 <default-interceptor-ref name="surveyparkStack"></default-interceptor-ref>
除了須要聲明登陸攔截器以外,還須要將默認棧改變成本身的攔截器棧surveyparkStack。
3.定義全局結果集,跳轉到登錄頁面
<global-results> <result name="toLoginPage">/index.jsp</result> </global-results>
4.這裏須要注意的是,須要將登錄Action和註冊Action單獨給拿出來,不然會陷入死循環中,好比訪問登錄頁面被攔截轉到登錄頁面再被攔截。。。。。。這樣的最終結果就是stackOverFlow,爲了作到這一點,因此才單獨作了一個Action給登錄,單獨一個Action給Register。
4、新建調查
新建調查的流程就是:單擊新建調查超連接->SurveyAction調用createNewSurvey方法->重定向到顯示全部調查列表Action->查詢全部調查->轉發到顯示全部調查的頁面。
這裏新建的調查代碼以下SurveyServiceImpl.createNewSurvey(User user):
1 public void createNewSurvey(User user) { 2 Survey survey=new Survey(); 3 survey.setUser(user); 4 5 Page page=new Page(); 6 page.setSurvey(survey); 7 survey.getPages().add(page); 8 9 pageDao.saveEntity(page); 10 surveyDao.saveEntity(survey); 11 }
能夠看出來,新建調查以後該調查就有一個默認頁了。並且因爲在Bean類中大多數字段都有默認值,因此保存到數據庫中的字段大多都有默認值。
5、查詢調查
因爲User沒有關聯到Survey,因此不能直接根據User對象獲取Survey對象列表。須要直接使用hql查詢Survey對象獲取。
String hql="from Survey where user.userId=?"; List<Survey> surveys=this.surveyDao.findEntityByHQL(hql, user.getUserId());
效果以下圖所示: