登錄攔截實現步驟
一:前提條件
此時我們的ssj項目已經搭建完成,最好是簡單的crud功能已經完成。這裏簡單介紹一下思路:在我們新增或者完善一個項目的功能時我們要有大概的思路。那麼什麼是登錄攔截呢,互聯網時代我們在生活中經常接觸,可以說手機app及網頁上必不可少的一項。在我們進入app或淘寶網頁時會讓你先登錄個人賬號,此時一般必有用戶名和密碼兩項,當然現在很多會加上手機驗證碼。本文先介紹驗證用戶名和密碼,當我們在前臺頁面填寫用戶名和密碼並點擊提交後,後臺根據用戶名查找user數據,若不存在就提示用戶名不存在,若用戶名存在就拿該user數據庫信息的密碼和輸入的密碼對比(這裏的密碼加密及解密就不贅述了)若密碼正確則驗證通過,若錯誤則提示密碼錯誤。該項功能需要前端頁面+controller+loginInterceptor與數據庫交互共同完成。loginInterceptor在每個controller方法使用時都會驗證攔截。
二:登錄攔截頁面
這是我的項目登陸頁面(驗證碼本文不多講,如有需要後續會寫一篇驗證碼相關的小功能),當用戶輸入用戶名密碼後,點擊提交會發送一個ajax請求,此時controller層接收到用戶名和密碼。
三:controller層業務操作
@RequestMapping("login")
@ResponseBody
public Map<String,Object> login(
String username,
String password,
String code,
HttpSession session
){
Map<String,Object> result = new HashMap<String, Object>();
User userByUsername = null;
if(StringUtils.isNotBlank(username)) {
userByUsername = userService.findByUserName(username);
//1驗證用戶名
if(userByUsername == null) {
result.put("success", false);
result.put("msg", "用戶名不存在!");
return result;
}
}
//2驗證驗證碼
if(StringUtils.isNotBlank(code)) {
String checkCode = (String) session.getAttribute("checkCode");
if(!checkCode.trim().equals(code.trim())) {
result.put("success", false);
result.put("msg", "用戶驗證碼不正確!");
return result;
}
}else {
result.put("success", false);
result.put("msg", "用戶驗證碼不能爲空!");
return result;
}
//3驗證密碼
if(!MD5Util.verify(password, userByUsername.getPassword())){//密碼不對
result.put("success", false);
result.put("msg", "用戶密碼不正確!");
return result;
}else {//密碼對
session.setAttribute("user", userByUsername);
result.put("success", true);
result.put("msg", "登陸成功");
return result;
}
controller層邏輯:當我們在前臺頁面填寫用戶名和密碼並點擊提交後,後臺根據用戶名查找user數據,若不存在就提示用戶名不存在,若用戶名存在就拿該user數據庫信息的密碼和輸入的密碼對比(這裏的密碼加密及解密就不贅述了)若密碼正確則驗證通過,若錯誤則提示密碼錯誤。
此時驗證通過與否的關鍵代碼爲:session.setAttribute(“user”, userByUsername); 當我們所有驗證都通過是表明我們的用戶是存在的,那麼我們將用戶信息放到session會話中,然後在loginInterceptor中驗證。
四:LoginInterceptor層業務操作
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");//其實就是查詢session中是否有user
if(user != null) {
return true;
}else {//判斷是不是ajax請求//XMLHttpRequest//X-Requested-With
String head = request.getHeader("X-Requested-With");
if(StringUtils.isNotBlank(head) && head.equals("XMLHttpRequest")) {
Map<String, Object> result = new HashMap<String, Object>();
result.put("code",12345);
JsonUtil.outJson(response, result);
}else {
response.sendRedirect(request.getServletContext().getContextPath()+"/login.jsp");
}
return false;
}
}
這裏我們新建一個LoginLnterceptor類,繼承HandlerInterceptorAdapter 重寫preHandle方法,這裏我們可以重寫的方法有:
preHandle:在控制器方法調用前執行,返回值爲是否中斷,true,表示繼續執行(下一個攔截器或處理器),false則會中斷後續的所有操作,所以我們需要使用response來響應請求。
postHandle:在控制器方法調用後,解析視圖前調用,我們可以對視圖和模型做進一步渲染或修改。
afterCompletion:整個請求完成,即視圖渲染結束後調用,這個時候可以做些資源清理工作,或日誌記錄等。
afterConcurrentHandlingStarted:當Controller中有異步請求方法的時候會觸發該方法時,異步請求先支持preHandle、然後執行afterConcurrentHandlingStarted。
注意!!!這裏我們使用的是preHandler,在controller方法調用前執行,當session中user不爲空時,說明user信息存在即登陸成功,不需要攔截,則返回true。反之返回false。那就有個問題了:preHandle會攔截controller層的所有方法,那麼login方法豈不是一直都進不去嗎?因爲只有login方法成功後纔會在session中放入user。那麼這個問題就需要配置spring-mvc的攔截器白名單了。白名單無需驗證即可通過。
其實當我們在判斷用戶爲空即登錄不成功後又通過請求頭的方式String head = request.getHeader(“X-Requested-With”);判斷了該請求是不是ajax請求。
如果是ajax請求呢,用戶是不會跳轉的,雖然用戶的操作被攔截,但是用戶卻不知道。所以我們可以在攔截成功的時候,響應一個字符。(JsonUtil.outJson(response, result);)這裏我向前臺傳遞一個map集合值爲:12345。當前臺收到後可以提醒用戶登陸失敗。
如果不是ajax請求則可以直接獲取項目上下文路徑後response重定向到login.jsp。讓用戶重新登陸。
五:spring-mvc的攔截器及白名單配置
寫到這裏小編的電腦硬盤出了些故障,配置信息等電腦修好後再補上吧。
六:寫在最後
總結登陸攔截器,其實就是在controller層每個方法之前加上一個驗證即interceptor的session驗證。當驗證通過後可以在一次session回話中訪問任何方法及跳轉頁面。本文爲小編個人理解所做,如有錯誤請聯繫我修改或刪除。
最後的最後祝大家2020520快樂!!!可惜我錯過了整個紀元。啦啦啦,各位下個博客見!