攔截器 應用詳解--SpringMVC


在實際項目中,攔截器的使用是非常普遍的,例如在購物網站中通過攔截器可以攔截未登錄的用戶,禁止其購買商品,或者使用它來驗證已登錄用戶是否有相應的操作權限等,Spring MVC提供了攔截器功能,通過配置即可對請求進行攔截處理。

 

攔截器的定義:

要使用Spring MVC中的攔截器,就需要對攔截器類進行定義和配置。通常攔截器類可以通過兩種方式來定義。一種是通過實現HandlerInterceptor接口,或繼承HandlerInterceptor接口的實現類(如HandlerInterceptorAdapter)來定義;另一種是通過實現WebRequestInterceptor接口,或繼承WebRequestInterceptor接口的實現類來定義。

以實現HandlerInterceptor接口的定義方式為例,自定義攔截器類的代碼如下所示:

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {    
        
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {

    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        return false;
    }
}

 

關於這三個方法的具體描述如下:

(1)preHandler()方法:該方法會在控制器方法前執行,其返回值表示是否中斷后續操作。當其返回值為true時,表示繼續向下執行;當其返回值為false時,會中斷后續的所有操作(包括調用下一個攔截器和控制器類中的方法執行等)。

(2)postHandle()方法:該方法會在控制器方法調用之后,其解析試圖之前執行。可以通過此方法對請求域中的模型和試圖做出進一步的修改。

(3)afterCompletion()方法:該方法會在整個請求完成,即視圖渲染結束之后執行。可以通過次方法實現一些資料清理、記錄日志信息等工作。

 

攔截器的配置:

要使自定義的攔截器類生效,還需要在Spring MVC的配置文件中進行配置,配置代碼如下:

<!-- 配置攔截器 -->
<mvc:interceptors>
    <!-- 使用bean直接定義在<mvc:interceptors>下面的Interceptor將攔截所有請求 -->
    <bean class="com.neuedu.interceptor.LoginInterceptor" />
    <!-- 攔截器1 -->
    <mvc:interceptor>
        <!-- 配置攔截器作用的路徑 -->
        <mvc:mapping path="/**" />
        <!-- 配置不需要攔截器作用的路徑 -->
        <mvc:exclude-mapping path="" />
        <!-- 定義在<mvc:interceptor>下面的,表示對匹配路徑的請求才進行攔截 -->
        <bean class="com.neuedu.interceptor.interceptor1" />
    </mvc:interceptor>
    <!-- 攔截器2 -->
    <mvc:interceptor>
        <mvc:mapping path="/hello" />
        <bean class="com.neuedu.interceptor.interceptor2" />
    </mvc:interceptor>
</mvc:interceptors>

在上述代碼中,<mvc:interceptors>元素用於配置一組攔截器,其子元素<bean>中定義是全局攔截器,它會攔截所有的請求;而<mvc:interceptor>元素中定義的是指定路徑的攔截器,它會對指定路徑下的請求生效。<mvc:interceptor>元素的子元素<mvc:mapping>用於配置攔截器作用的路徑,該路徑在其屬性path中定義。如上述代碼path的屬性值“/**”表示攔截所有路徑,“/hello”表示攔截所有以“/hello”結尾的路徑。如果在請求路徑中包含不需要攔截的內容,還可以通過<mvc:exclude-mapping>元素進行配置。

需要注意的是,<mvc:interceptor>中的子元素必須按照上述代碼的配置順序進行編寫,即<mvc:mapping> -> <mvc:exclude-mapping> -> <bean>的順序,否則文件會報錯。

 

單個攔截器的執行流程如下:

程序首先會執行攔截器類中的preHandle()方法,如果該方法的返回值為true,則程序會繼續向下執行處理器中的方法,否則將不再向下執行;在業務處理器(即控制器Controller類)處理完請求后,會執行postHandle()方法,然后會通過DispatcherServlet向客戶端返回響應;在DispatcherServlet處理完請求后,才會執行afterCompletion()方法。

 

多個攔截器的執行流程:

當多個攔截器同時工作時,它們的preHandle()方法會按照配置文件中攔截器的配置順序執行,而它們的postHandle()方法和afterCompletion()方法則會按照配置順序的反序執行。

假設有兩個攔截器Interceptor1和interceptor2,並且在配置文件中,Interceptor1攔截器配置在前。

 

 

 

接下來我們通過攔截器來完成一個用戶登錄權限驗證的案例。

本案例中,只有登陸后的用戶才能訪問系統中的主頁面,如果沒有登錄系統而直接訪問主頁面,則攔截器會將請求攔截,並轉發到登錄頁面,同時在登錄頁面中給出提示信息。如果用戶名或密碼錯誤,也會在登錄頁面給出相應的提示信息。當已登錄的用戶在系統主頁中單擊“退出”鏈接時,系統同樣會回到登錄頁面。

(1)在eclipse中新建一個動態web項目,在lib目錄下導入相關Sping MVC的JAE包,搭建Spring MVC的環境。

(2)在src目錄下,創建一個com.neuedu.pojo包,並在包中創建User類。在User類中,代碼如下:

package com.neuedu.pojo;

public class User {
    private Integer id;//id
    private String username;//用戶名
    private String password;//密碼
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

 

(3)在src目錄下,新建com.neuedu.controller包,創建控制器類UserController,並在該類中定義向主頁跳轉、向登錄頁面跳轉、執行用戶登錄等操作的方法,代碼如下:

package com.neuedu.controller;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.neuedu.pojo.User;

@Controller
public class UserController {
    /*
     * 向用戶登錄頁面跳轉
     * */
    @RequestMapping(value="/login",method=RequestMethod.GET)
    public  String toLogin() {
        return "login";
    }
    /*
     * 用戶登錄
     * */
    @RequestMapping(value="/login",method=RequestMethod.POST)
    public String login(User user,Model model,HttpSession session) {
        //獲取用戶名和密碼
        String username = user.getUsername();
        String password = user.getPassword();
        //此處模擬從數據庫中獲取用戶名和密碼后進行判斷
        if(username != null && username.equals("wangyifei")
                && password != null && password.equals("123456")) {
            //將用戶對象添加到Session
            session.setAttribute("USER_SESSION", user);
            //向主頁面跳轉
            return "main";
        }
        model.addAttribute("msg","用戶名或密碼錯誤,請重新登錄!");
        return "login";
    }
    
    /*
     * 向用戶主頁面跳轉
     * */
    @RequestMapping(value="/main")
    public String toMain() {
        return "main";
    }
    
    /*
     * 退出登錄
     * */
    @RequestMapping(value="/logout")
    public String logout(HttpSession session) {
        //清除Session
        session.invalidate();
        //向登錄頁面跳轉
        return "login";
    }
    
}

 

(4)在src目錄下,新建com.neuedu.interceptor包,創建攔截器類LoginInterceptor,代碼如下:

package com.neuedu.interceptor;

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;

import com.neuedu.pojo.User;

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {    
        
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {

    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //獲取請求的URL
        String url = request.getRequestURI();
        //URL:除了login.jsp是可以公開訪問的,其他的URL都進行攔截控制
        if(url.indexOf("/login")>=0) {
            return true;
        }
        //獲取Session
        HttpSession session = request.getSession();
        User user = (User)session.getAttribute("USER_SESSION");
        //判斷Session中是否有用戶數據,如果有,則返回true,繼續向下執行
        if(user != null) {
            return true;
        }
        //不符合條件的給出提示信息,並轉發到登錄頁面
        request.setAttribute("msg","您還沒有登錄,請先登錄!");
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }
}

 

(5)配置文件springmvc-config.xml代碼如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 定義組件掃描器,指定需要掃描的包 -->
    <context:component-scan base-package="com.neuedu.controller"/>
    <!-- 配置注解驅動 -->
    <mvc:annotation-driven />
    <!-- 定義視圖解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 設置前綴 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 設置后綴 -->
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!-- 配置攔截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.neuedu.interceptor.LoginInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
    
</beans>

 

(6)在WEB-INF目錄下新建jsp文件夾中,創建一個系統主頁面main.jsp,代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

    當前用戶:${USER_SESSION.username }
    <a href="${pageContext.request.contextPath }/logout">退出</a>
    
</body>
</html>

 

(7)在jsp文件夾創建一個login.jsp,在頁面中編寫一個用於實現登錄操作的form表單,代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    ${msg }
    <form action="${pageContext.request.contextPath }/login.action" method="POST">
        用戶名:<input type="text" name="username" /><br />&nbsp;&nbsp;&nbsp;碼:
        <input type="password" name="password" /><br />
        <input type="submit" value="登錄" />
    </form>
</body>
</html>

 

(8)web.xml文件配置代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>interceptor</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
  <!-- 配置 DispatcherServlet 前端控制器 -->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    
        <!-- 在此處調用 springmvc.xml 文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-config.xml</param-value>
        </init-param>

        <!-- 在 tomcat 服務器啟動的時候,最先加載它 -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>
  
</web-app>

 

(9)整個項目目錄結構如下:

 

(10)將項目發布到Tomcat服務器並啟動,在瀏覽器中訪問地址 http://localhost:8080/interceptor/main.action,效果如下:

 

未登錄,不能直接訪問主頁面!

 

輸入錯誤用戶名“java”和密碼“123456”,給出提示!

 

 

輸入正確用戶名“wangyifei”和密碼“123456”,成功進入主頁面!

 

 

 

轉載請標明出處,謝謝~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM