天天看點

SpringMvc Interceptor攔截器的配置與使用

package com.springmvc.controller;

import com.springmvc.entity.User;
import com.springmvc.service.UserService;
import org.apache.commons.collections.map.HashedMap;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class ViewController {

    private Logger logger = Logger.getLogger(ViewController.class);

    @Resource(name = "UserService")
    private UserService userService;

    @RequestMapping("/index")
    public String index() {
        logger.info("進入 index 方法");
        return "index";
    }

    @RequestMapping("/find")
    @ResponseBody
    public Map<String, Object> find(User user, HttpServletRequest request) {
        Map<String, Object> map = new HashedMap();
        logger.info("進入 find 方法");
        List<User> loginuser = userService.findByUsernameAndPwd(user.getUsername(), user.getPassword());
        if (loginuser != null) {
            map.put("result", "success");
        } else {
            map.put("result", "fail");
        }
        return map;
    }

    @RequestMapping("/success")
    public String success() {
        logger.info("進入 success 方法");
        return "success";
    }
}
           
package com.springmvc.intercepter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    private final static Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("進入 preHandle 方法..." + request.getRequestURL().toString() + "," + request.getRequestURI());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.info("進入 postHandle 方法..." + request.getRequestURL().toString() + "," + request.getRequestURI());
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.info("進入 afterCompletion 方法..." + request.getRequestURL().toString() + "," + request.getRequestURI());
    }
}
           

spring-mvc.xml:

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/user/index"/>
            <bean class="com.springmvc.intercepter.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
           

user/index

SpringMvc Interceptor攔截器的配置與使用

點選登入,先執行user/find,然後執行user/success,成功後:

SpringMvc Interceptor攔截器的配置與使用

攔截去除/user/index,是以日志不輸出preHanle,postHandle,afterCompletion這三個方法的日志

攔截沒有去除/user/find,是以日志輸出preHanle,postHandle,afterCompletion這三個方法的日志

攔截沒有去除/user/success,是以日志輸出preHanle,postHandle,afterCompletion這三個方法的日志

仔細看日志,從啟動到登入成功(日志後面有驚喜)

2018-02-28 17:32:40,869 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (12488ms)] - Last-Modified value for [/user/index] is: -1
2018-02-28 17:32:40,870 -[INFO]  method:[com.springmvc.controller.ViewController (12489ms)] - 進入 index 方法
2018-02-28 17:32:41,086 -[DEBUG]  method:[org.springframework.web.servlet.view.BeanNameViewResolver (12705ms)] - No matching bean found for view name 'index'
2018-02-28 17:32:41,087 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (12706ms)] - Rendering view [org.springframework.web.servlet.view.JstlView: name 'index'; URL [/WEB-INF/page/index.jsp]] in DispatcherServlet with name 'SpringMVC'
2018-02-28 17:32:41,087 -[DEBUG]  method:[org.springframework.web.servlet.view.JstlView (12706ms)] - Forwarding to resource [/WEB-INF/page/index.jsp] in InternalResourceView 'index'
2018-02-28 17:32:41,088 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (12707ms)] - Successfully completed request
2018-02-28 17:33:03,505 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (35124ms)] - DispatcherServlet with name 'SpringMVC' processing POST request for [/user/find]
2018-02-28 17:33:03,508 -[DEBUG]  method:[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping (35127ms)] - Looking up handler method for path /user/find
2018-02-28 17:33:03,508 -[DEBUG]  method:[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping (35127ms)] - Returning handler method [public java.util.Map<java.lang.String, java.lang.Object> com.springmvc.controller.ViewController.find(com.springmvc.entity.User,javax.servlet.http.HttpServletRequest)]
2018-02-28 17:33:03,508 -[DEBUG]  method:[org.springframework.beans.factory.support.DefaultListableBeanFactory (35127ms)] - Returning cached instance of singleton bean 'viewController'
2018-02-28 17:33:05,084 -[INFO]  method:[com.springmvc.intercepter.MyIntercepter (36703ms)] - 進入 preHandle 方法...http://localhost:8080/user/find,/user/find
2018-02-28 17:33:05,144 -[INFO]  method:[com.springmvc.controller.ViewController (36763ms)] - 進入 find 方法
2018-02-28 17:33:05,326 -[DEBUG]  method:[org.mybatis.spring.SqlSessionUtils (36945ms)] - Creating a new SqlSession
2018-02-28 17:33:05,343 -[DEBUG]  method:[org.mybatis.spring.SqlSessionUtils (36962ms)] - SqlSession [[email protected]] was not registered for synchronization because synchronization is not active
2018-02-28 17:33:05,446 -[DEBUG]  method:[org.springframework.jdbc.datasource.DataSourceUtils (37065ms)] - Fetching JDBC Connection from DataSource
2018-02-28 17:33:05,488 -[DEBUG]  method:[org.mybatis.spring.transaction.SpringManagedTransaction (37107ms)] - JDBC Connection [[email protected]] will not be managed by Spring
2018-02-28 17:33:05,546 -[DEBUG]  method:[com.springmvc.dao.UserDao.findByUsernameAndPwd (37165ms)] - ==>  Preparing: SELECT id, username, password, sex FROM t_user WHERE username =? AND password =? 
2018-02-28 17:33:05,628 -[DEBUG]  method:[com.springmvc.dao.UserDao.findByUsernameAndPwd (37247ms)] - ==> Parameters: Tom(String), 123(String)
2018-02-28 17:33:05,696 -[DEBUG]  method:[com.springmvc.dao.UserDao.findByUsernameAndPwd (37315ms)] - <==      Total: 1
2018-02-28 17:33:05,698 -[DEBUG]  method:[com.alibaba.druid.pool.PreparedStatementPool (37317ms)] - {conn-10001, pstmt-20000} enter cache
2018-02-28 17:33:05,699 -[DEBUG]  method:[org.mybatis.spring.SqlSessionUtils (37318ms)] - Closing non transactional SqlSession [[email protected]]
2018-02-28 17:33:05,700 -[DEBUG]  method:[org.springframework.jdbc.datasource.DataSourceUtils (37319ms)] - Returning JDBC Connection to DataSource
2018-02-28 17:33:05,762 -[DEBUG]  method:[org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain (37381ms)] - Invoking ResponseBodyAdvice chain for body={result=success}
2018-02-28 17:33:05,763 -[DEBUG]  method:[org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain (37382ms)] - After ResponseBodyAdvice chain body={result=success}
2018-02-28 17:33:05,779 -[DEBUG]  method:[org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor (37398ms)] - Written [{result=success}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@1782747b]
2018-02-28 17:33:06,555 -[INFO]  method:[com.springmvc.intercepter.MyIntercepter (38174ms)] - 進入 postHandle 方法...http://localhost:8080/user/find,/user/find
2018-02-28 17:33:06,556 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (38175ms)] - Null ModelAndView returned to DispatcherServlet with name 'SpringMVC': assuming HandlerAdapter completed request handling
2018-02-28 17:33:06,795 -[INFO]  method:[com.springmvc.intercepter.MyIntercepter (38414ms)] - 進入 afterCompletion 方法...http://localhost:8080/user/find,/user/find
2018-02-28 17:33:06,796 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (38415ms)] - Successfully completed request
2018-02-28 17:33:06,815 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (38434ms)] - DispatcherServlet with name 'SpringMVC' processing GET request for [/user/success]
2018-02-28 17:33:06,816 -[DEBUG]  method:[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping (38435ms)] - Looking up handler method for path /user/success
2018-02-28 17:33:06,817 -[DEBUG]  method:[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping (38436ms)] - Returning handler method [public java.lang.String com.springmvc.controller.ViewController.success()]
2018-02-28 17:33:06,817 -[DEBUG]  method:[org.springframework.beans.factory.support.DefaultListableBeanFactory (38436ms)] - Returning cached instance of singleton bean 'viewController'
2018-02-28 17:33:06,818 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (38437ms)] - Last-Modified value for [/user/success] is: -1
2018-02-28 17:33:07,203 -[INFO]  method:[com.springmvc.intercepter.MyIntercepter (38822ms)] - 進入 preHandle 方法...http://localhost:8080/user/success,/user/success
2018-02-28 17:33:07,204 -[INFO]  method:[com.springmvc.controller.ViewController (38823ms)] - 進入 success 方法
2018-02-28 17:33:07,423 -[INFO]  method:[com.springmvc.intercepter.MyIntercepter (39042ms)] - 進入 postHandle 方法...http://localhost:8080/user/success,/user/success
2018-02-28 17:33:07,424 -[DEBUG]  method:[org.springframework.web.servlet.view.BeanNameViewResolver (39043ms)] - No matching bean found for view name 'success'
2018-02-28 17:33:07,425 -[DEBUG]  method:[org.springframework.beans.factory.support.DefaultListableBeanFactory (39044ms)] - Invoking afterPropertiesSet() on bean with name 'success'
2018-02-28 17:33:07,425 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (39044ms)] - Rendering view [org.springframework.web.servlet.view.JstlView: name 'success'; URL [/WEB-INF/page/success.jsp]] in DispatcherServlet with name 'SpringMVC'
2018-02-28 17:33:07,426 -[DEBUG]  method:[org.springframework.web.servlet.view.JstlView (39045ms)] - Forwarding to resource [/WEB-INF/page/success.jsp] in InternalResourceView 'success'
2018-02-28 17:33:07,695 -[INFO]  method:[com.springmvc.intercepter.MyIntercepter (39314ms)] - 進入 afterCompletion 方法...http://localhost:8080/user/success,/user/success
2018-02-28 17:33:07,695 -[DEBUG]  method:[org.springframework.web.servlet.DispatcherServlet (39314ms)] - Successfully completed request
           

去除攔截,方法執行順序:

ViewController.index()

攔截,方法執行順序:(由上至下)

HandlerExecutionChain.applyPreHandle()

MyInterceptor.preHandle()

ViewController.find()

HandlerExecutionChain.applyPostHandle()

MyInterceptor.postHandle()

HandlerExecutionChain.triggerAfterCompletion()

MyInterceptor.afterCompletion()

跳轉到新頁面

配置說明:

<!-- 配置用于session驗證的攔截器 -->
    <!-- 
        如果有多個攔截器滿足攔截處理的要求,則依據配置的先後順序來執行
     -->
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 攔截所有的請求,這個必須寫在前面,也就是寫在【不攔截】的上面 -->
            <mvc:mapping path="/**" />
            <!-- 但是排除下面這些,也就是不攔截請求 -->
            <mvc:exclude-mapping path="/login.html" />
            <mvc:exclude-mapping path="/account/login.do" />
            <mvc:exclude-mapping path="/account/regist.do" />
            <bean class="com.msym.cloudnote.interceptors.SessionInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
           
  1. preHandle在業務處理器處理請求之前被調用;
  2. postHandle在業務處理器處理請求執行完成後,生成視圖之前執行;
  3. afterCompletion在DispatcherServlet完全處理完請求後被調用,可用于清理資源等 。afterCompletion()執行完成後開始渲染頁面

如果preHandle傳回false,則請求不再往下處理。

參考:https://www.cnblogs.com/daimajun/p/7172208.html

http://blog.csdn.net/huangjp_hz/article/details/73614314

之前一直不明白攔截器幹啥的,覺得很高大上,其實也沒啥,攔截器就是攔截某些請求的,同時會附加一些處理。

SpringMvc Interceptor攔截器的配置與使用