1. 程式人生 > >SpringMVC之攔截器實現登錄驗證

SpringMVC之攔截器實現登錄驗證

一個 throw idt 判斷 sed XML auto 也有 登錄驗證

今天回頭看之前發的javaweb學習路線圖,發現把路線圖中的也學的有一半多了,不過還是路漫漫。在前面的博客中有學習過spring的aop,它利用動態代理實現,在springmvc中也是一樣,今天使用HandlerInterceptor來實現登錄權限驗證。我們平時在做系統時有些頁面是需要先登錄才能訪問的,一種方法是在每個請求方法中都做登錄判斷,這樣頂多是把登錄功能封裝起來,以後沒新增一個代碼都要加上,這樣很不方便。其實這裏我們可以使用攔截器進行登錄驗證,判斷是否有session,如果有session就斷定已經登錄。攔截器不僅僅可以做登錄,它做登錄完成之後可能還有根據用戶角色限制頁面或工具的權限,我們還可以再增加一個攔截器,來判斷用戶權限等。還可以使用它做防盜鏈,這個防盜鏈的之前博客中也有類似的實現,今天就只演示下登錄。

一、創建控制器

1.這裏創建了LoginIntercepter類實現HandlerInterceptor來創建控制器.HandlerInterceptor它有3個方法,preHandle,postHandle,afterCompletion,3個方法在之前學習springmvc工作流程的時候也有介紹。我們做登錄驗證主要是在preHandle方法中來做校驗。這裏判斷是不是登錄頁面,登錄頁面不能被攔截,不然它始終登錄不上.然後判斷是否有session,如果有則當做登錄成功,沒有則跳轉到登錄頁面.

技術分享圖片
package com.cyw.web.Intercepter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginIntercepter implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { // TODO Auto-generated method stub String requestURI = request.getRequestURI(); if(requestURI.indexOf("/login")<=0){ //說明處在編輯的頁面 HttpSession session = request.getSession(); String username = (String) session.getAttribute("username"); if(username!=null){ //登陸成功的用戶 return true; }else{ //沒有登陸,轉向登陸界面 request.getRequestDispatcher("../view/Login.jsp").forward(request,response); // response.sendRedirect("../login/login.action"); return false; } }else{ return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } }
View Code

2.攔截器配置 在spring-mvc.xml中進行配置

技術分享圖片
    <mvc:interceptors> 
        <mvc:interceptor><mvc:mapping path="/**"/><bean class="com.cyw.web.Intercepter.LoginIntercepter"/></mvc:interceptor> 
        <mvc:interceptor><mvc:mapping path="/**"/><bean class="com.cyw.web.Intercepter.LoginWebRequestInterceptor"/></mvc:interceptor> 
    </mvc:interceptors> 
View Code

這裏配置了兩個攔截器,LoginWebRequestInterceptor這個也是一攔截器.

二、創建jsp頁面

這裏創建了一個login.jsp的登錄頁面.

技術分享圖片
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="../login/login.action" method="post">  
         姓名:<input type="text" name="username"> <br><br>  
         密碼:   <input type="text" name="password"> <br><br>  
         <input type="submit" value="登陸">  
</form> 
</body>
</html>
View Code

三、創建LoginController

這裏創建了LoginController用來接收登錄的post請求.

技術分享圖片
package com.cyw.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/login")
public class LoginController {
    @RequestMapping(value = "/login.action",method = RequestMethod.GET)
    public ModelAndView login(HttpServletRequest request,HttpServletResponse response){  
         ModelAndView modelAndView = new ModelAndView("Login");
         return modelAndView;
    }
    @RequestMapping(value = "login.action",method = RequestMethod.POST)
    public String clientLogin(HttpServletRequest request,HttpServletResponse response){ 
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        if(username.equals("cuiyw")&&password.equals("123456")){  
            //登陸成功  
            request.getSession().setAttribute("username",username);  
            return "forward:/hello/testModelAndView";  
        }else{  
            //登陸失敗  
            return "forward:/login/login.action";  
        }  
    } 

}
View Code

但是上面的代碼就會出現問題HTTP Status 405 – Method Not Allowed ,Request method ‘POST‘ not supported。

技術分享圖片

為什麽會出現這個錯誤呢?我開始以為是LoginController中的@RequestMapping配置有問題,但找了好久也沒找到,而且再次輸入頁面時顯示的是登錄成功的,意思是session也是設置上的,抱著嘗試的心態把return中的forward改成redirect,沒想到成功了。這就尷尬了,這就涉及到forward與redirect的區別。

四、forward與redirect的區別

forward過程
轉發,服務器端行為。web服務器把接受的請求,調用內部的方法在容器內部完成請求處理和轉發動作,然後響應客戶端,在這裏,轉發的路徑必須是同一個web容器下的url,其不能轉向到其他的web路徑上去,中間傳遞的是自己的容器內的request。
redirect過程
重定向,客戶端行為。客戶端發送http請求,web服務器接受後發送3**狀態碼響應及對應新的location給客客戶端,客戶端發現是3**響應,則自動再發送一個新的http請求,請求url是新的location地址,在這裏location可以重定向到任意URL,既然是瀏覽器重新發出了請求,則就沒有什麽request傳遞的概念了。重定向行為是瀏覽器做了至少兩次的訪問請求。

五、問題原因

上面的forward與redirect的區別也有介紹它們兩個的區別,forward用的還是同一個請求,只是把這個請求轉給另一個方法處理,redirect是響應給客戶端3開頭的狀態碼,然後客戶端再次請求,這裏我們登錄的是post請求,而/hello/testModelAndView對應的testModelAndView方法設置的method = RequestMethod.GET,就沒有post,所以報405的錯誤。

六、WebRequestInterceptor攔截器

springmvc中還可以使用WebRequestInterceptor來做攔截器,用法和HandlerInterceptor差不多,也是現實WebRequestInterceptor,然後重寫父類的方法,配置到spring-mvc.xml中。實現的方法名是一樣的,只是HandlerInterceptor中使用的HttpServletRequest,WebRequestInterceptor中使用的是WebRequest.

七.小結

其實原本不打算寫攔截器呢,因為springmvc的參數傳遞還沒寫完,所以下篇還是要接著寫參數傳遞,json與Controller的交互.

SpringMVC之攔截器實現登錄驗證