SpringMVC拦截器-基于拦截器实现控制方法监控,计算控制层方法时长

1.1. Spring MVC拦截器概述

拦截器是SpringMVC中的一个核心应用组件,主要用于处理多个
Controller的共性问题.当我们的请求由DispatcherServlet派发
到具体Controller之前首先要执行拦截器中一些相关方法,在这些
方法中可以对请求进行相应预处理(例如权限检测,参数验证),这些方法可以决定对这个请求进行拦截还是放行。
通过spring mvc 架构图分析,拦截器在Spring MVC中处理流程中的一个位置


请求到达后端控制器之前有一堆拦截器,拦截器在请求到达后端控制器之前可以做一些预处理。从控制器返回的数据也可以在拦截器做预处理。拦截器有拦截器链,过滤器有过滤器链。通常把拦截器和Controller称为执行链中的一个对象。过滤器是请求到达前端控制器之前执行,拦截器是前端控制器到达后端控制器之前执行,他们两个所处的位置不同。所以在过滤器里取不到后端控制器。先执行的拦截器最后结束。后结束的拦截器最先结束。

1)假如对请求数据进行编码,是应在过滤器还是拦截器?
推荐使用过滤器
2)拦截器有哪些有些应用场景呢?(处理后台控制业务的共性-对请求进行拦截不让其传入后端控制器)
a)进行身份认证(判定用户是否是合法用户)
b)进行系统监控
c)进行日志记录

1.2. Spring MVC拦截器编写及基本配置

拦截器如何编写?
我们自己编写Spring MVC拦截器需要实现HandlerInterceptor接口或者继承此接口的实现类 HandlerInterceptorAdapter(继承这个类时可根据需求重写必要的方法)
/spring-mvc-v2/src/main/resources/spring-configs.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="  
       http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd  
       http://www.springframework.org/schema/mvc   
       http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd   
       http://www.springframework.org/schema/tx   
       http://www.springframework.org/schema/tx/spring-tx-4.3.xsd   
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
       http://www.springframework.org/schema/util 
       http://www.springframework.org/schema/util/spring-util-4.3.xsd
       http://www.springframework.org/schema/data/jpa 
       http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">
       <!-- 配置spring中bean对象的扫描(包括后端控制器)
       component-scan元素用于包以及包中的子类并且将使用了@Controller,@Service类似注解等修饰的类
       交给Spring容器管理。 -->
       <context:component-scan base-package="controller"/>
       <!--配置和启用spring MVC默认配置(例如底层支持json)-->
       <mvc:annotation-driven/>
       <!--配置springMVC视图解析器(负责视图解析操作)-->
      <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀-->
        <property name="Prefix" value="/WEB-INF/pages/"></property>
      </bean>
      <!--配置拦截器对象-->
       <mvc:interceptors>
        <mvc:interceptor>
        <!--要拦截的路径url-->
            <mvc:mapping path="/**"/>
            <!--要排除的拦截路径url-->
            <mvc:exclude-mapping path="/doStudyInterceptor.do"/>
            <!--拦截器对象-->
            <bean class="controller.TimeInterceptor"/>
        </mvc:interceptor>
       </mvc:interceptors>
</beans>

/spring-mvc-v2/src/main/java/controller/InterceptorController.java

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class InterceptorController {
    @RequestMapping("doSomeThing")
    @ResponseBody
    public String doSomeThing() {
        System.out.println("InterceptorController.doSomeThing()");
        // 获取方法执行时长
        long startTime = System.nanoTime();
        String result = "do some thing";
        long endTime = System.nanoTime();
        System.out.println(endTime - startTime);
        return result;
    }

    @RequestMapping("doStudyInterceptor")
    @ResponseBody
    public String doStudyInterceptor() {
        System.out.println("InterceptorController.doStudyInterceptor()");
        // 获取方法执行时长
        long startTime = System.nanoTime();
        String result = "do study Interceptor";
        long endTime = System.nanoTime();
        System.out.println(endTime - startTime);
        return result;
    }
}

/spring-mvc-v2/src/main/java/controller/TimeInterceptor.java

package controller;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
 * 拦截器的编写:是实现HandlerInterceptor接口或继承HandlerInterceptorAdapter
 * 继承适配器只需要实现一部分功能
 * 拦截器的配置
 * 1)xml方式(spring-config.xml)
 * 2)基于annotation方式
 */
public class TimeInterceptor implements HandlerInterceptor{

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("TimeInterceptor.preHandle()");
        return true;//false表示拦截。true表示放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("TimeInterceptor.postHandle()");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("TimeInterceptor.afterCompletion()");
    }

}

http://localhost/spring-mvc-v2/doSomeThing.do
控制台输出

TimeInterceptor.preHandle()
InterceptorController.doSomeThing()
554
TimeInterceptor.postHandle()
TimeInterceptor.afterCompletion()

http://localhost/spring-mvc-v2/doStudyInterceptor.do
控制台输出

InterceptorController.doStudyInterceptor()
554

共性的方法提出
/spring-mvc-v2/src/main/java/controller/InterceptorController.java

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class InterceptorController {
    @RequestMapping("doSomeThing")
    @ResponseBody
    public String doSomeThing() {
        System.out.println("InterceptorController.doSomeThing()");
        // 获取方法执行时长
        String result = "do some thing";
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
        }
        return result;
    }

    @RequestMapping("doStudyInterceptor")
    @ResponseBody
    public String doStudyInterceptor() {
        System.out.println("InterceptorController.doStudyInterceptor()");
        // 获取方法执行时长
        String result = "do study Interceptor";
        try {
            Thread.sleep(6000);
        } catch (Exception e) {
        }
        return result;
    }
}

/spring-mvc-v2/src/main/java/controller/TimeInterceptor.java

package controller;

import java.lang.reflect.Method;

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

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 拦截器的编写:是实现HandlerInterceptor接口或继承HandlerInterceptorAdapter 继承适配器只需要实现一部分功能
 * 拦截器的配置 1)xml方式(spring-config.xml) 2)基于annotation方式
 */
public class TimeInterceptor implements HandlerInterceptor {

    public TimeInterceptor() {
        System.out.println("TimeInterceptor.TimeInterceptor()");
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("TimeInterceptor.preHandle()");
        long startTime = System.currentTimeMillis();
        // 没有共享就没有伤害
        request.setAttribute("startTime", startTime);
        return true;// false表示拦截。true表示放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("TimeInterceptor.postHandle()");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("TimeInterceptor.afterCompletion()");
        long endTime = System.currentTimeMillis();
        long startTime = (Long) request.getAttribute("startTime");
        long totalTime = endTime - startTime;
        System.out.println(handler.getClass().getName());
        //将handler向下转型(目的获取方法信息)
        if (handler instanceof HandlerMethod) {
            //将handler向下转型-获取方法相关信息
            HandlerMethod hMethod = (HandlerMethod) handler;
            //获取方法对象
            Method method = hMethod.getMethod();
            //获取执行方法所在的类的信息
            String beanCls = hMethod.getBeanType().getName();
            System.out.println(beanCls+"."+method.getName()+"()" + "总时长" + totalTime);
        }

    }

}


http://localhost/spring-mvc-v2/doSomeThing.do

TimeInterceptor.preHandle()
InterceptorController.doSomeThing()
TimeInterceptor.postHandle()
TimeInterceptor.afterCompletion()
org.springframework.web.method.HandlerMethod
controller.InterceptorController.doSomeThing()总时长5018

基于拦截器实现控制方法监控,计算控制层方法时长,判断哪些方法需要计算,哪些不需要

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容