首页 > 其他分享 >SpringMVC拦截器

SpringMVC拦截器

时间:2024-03-13 14:45:06浏览次数:19  
标签:拦截器 SpringMVC request System println public out

SpringMVC拦截器

拦截器介绍

  1. 拦截器同过滤器一样,都是面向切面编程—AOP的具体实现,符合横切关注点的功能都可以考虑使用AOP实现;
  2. 可以使用Interceptor来执行某些任务,例如在Controller处理请求之前编写日志,添加或配置更新配置;
  3. 在Spring中,当请求发送到Controller处理之前,他必须经过Interceptor(0个或多个);

拦截器作用

  • 日志记录:记录请求信息的日志,以便进行信息监控,信息统计等等;
  • 权限检查:如登录检测,进入处理器检测是否登录;
  • 性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间;
  • 通用行为:读取Cookie得到用户信息并将用户对象放入请求,只要是多个处理器都需要的即可使用拦截器实现;
package com.kuangstudy.config.handler;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("1-----preHandle----->");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("3-----postHandle----->");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("4-----afterCompletion----->");
    }
}


package com.kuangstudy.config.mvc;

import com.kuangstudy.config.handler.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {


    @Bean
    // 初始化拦截器放入到ioc容器中
    public LoginInterceptor getLoginInterceptor(){
        return new LoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
                // 1: 拦截器注册
                .addInterceptor(getLoginInterceptor())
                // 2: 给拦截器配置并且定义规则
                .addPathPatterns("/api/**");
    }
}

拦截器链の执行顺序

根据配置的先后顺序执行preHandler, postHandle和afterCompletion则相反

多拦截器执行流程

自定义拦截器

这是SpringMVC的拦截器

  1. 自定义拦截器必须实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter类,并且重写三个方法:

    • preHandler
      在目标Handler方法执行前执行; 返回true执行目标方法, 返回false阻止目标方法
    • postHandler
      在目标Handler方法执行后,视图生成前执行;
    • afterCompletion
      在目标Handler方法执行后,视图生成后执行;

    preHandler -(判断逻辑写在preHandler )-> Handler –> postHandler –> 视图 –> afterCompletion

  2. 创建一个SpringMVC的拦截器的配置类实现WebMvcConfigurer的接口,并且重写addInterceptors()方法,注册拦截器类,并且为当前拦截器类定义规则;

  3. 可以在xml配置配置拦截方式;

具体实现举例

LogInterceptor类:

public class LogInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        System.out.println("\n-------- LogInterception.preHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Start Time: " + System.currentTimeMillis());

        request.setAttribute("startTime", startTime);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("\n-------- LogInterception.postHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
    }

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

        long startTime = (Long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("End Time: " + endTime);

        System.out.println("Time Taken: " + (endTime - startTime));
    }
}

OldLoginInterceptor 类:

public class OldLoginInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("\n-------- OldLoginInterceptor.preHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Sorry! This URL is no longer used, Redirect to /admin/login");
		// 在控制层之前,所有请求都进入这里,被重定向到/admin/login
        response.sendRedirect(request.getContextPath()+ "/admin/login");
        return false;
    }

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

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

配置拦截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor());

        registry.addInterceptor(new OldLoginInterceptor()).addPathPatterns("/admin/oldLogin");

        registry.addInterceptor(new AdminInterceptor()).addPathPatterns("/admin/*").excludePathPatterns("/admin/oldLogin");
    }
}

解析:

	LogInterceptor 拦截器用于拦截所有请求; 
	OldLoginInterceptor 用来拦截链接 “ / admin / oldLogin”,它将重定向到新的 “ / admin / login”。;
	AdminInterceptor用来拦截链接 “/admin/*”,除了链接 “ / admin / oldLogin”。

自定义Controller验证拦截器

@Controller
public class LoginController {

    @RequestMapping("/index")
    public String index(Model model){
        return "index";
    }

    @RequestMapping(value = "/admin/login")
    public String login(Model model){
        return "login";
    }
}

登录检测

流程:

  1. 访问需要登录的资源时,由拦截器重定向到登录页面;
  2. 如果访问的是登录页面,拦截器不应该拦截;
  3. 用户登录成功后,往Cookie/session中添加登录成功的标识(如用户编号);
  4. 下次请求时,拦截器通过判断Cookie/session中是否有该标识来决定继续流程还是到登录页面;
  5. 在此拦截器还应该允许游客访问的资源(看具体业务需要);
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        boolean flag = true;
        String ip = request.getRemoteAddr();
        long startTime = System.currentTimeMillis();
        request.setAttribute("requestStartTime", startTime);
        if (handler instanceof ResourceHttpRequestHandler) {
            System.out.println("preHandle这是一个静态资源方法!");
        } else if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            System.out.println("用户:" + ip + ",访问目标:" + method.getDeclaringClass().getName() + "." + method.getName());
        }

        //如果用户未登录
        User user = (User) request.getSession().getAttribute("user");
        if (null == user) {
            //重定向到登录页面
            response.sendRedirect("toLogin");
            flag = false;
        }
        return flag;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (handler instanceof ResourceHttpRequestHandler) {
            System.out.println("postHandle这是一个静态资源方法!");
        } else if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            long startTime = (long) request.getAttribute("requestStartTime");
            long endTime = System.currentTimeMillis();
            long executeTime = endTime - startTime;

            int time = 1000;
            //打印方法执行时间
            if (executeTime > time) {
                System.out.println("[" + method.getDeclaringClass().getName() + "." + method.getName() + "] 执行耗时 : "
                        + executeTime + "ms");
            } else {
                System.out.println("[" + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "] 执行耗时 : "
                        + executeTime + "ms");
            }
        }
    }

}

标签:拦截器,SpringMVC,request,System,println,public,out
From: https://www.cnblogs.com/code-jia/p/18070601

相关文章

  • springmvc入门登录功能
    学习springmvc的时候的一个入门功能,登录功能。配置好web框架,导入需要springjar包和springmvc需要的两个jar包,就可以编码了,首先写了登录需要的jsp页面<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>Title</title></hea......
  • 过滤器和拦截器的辨析
    过滤器和拦截器的辨析介绍过滤器和拦截器都是为了在请求到达目标处理器(Servlet或Controller)之前或者之后插入自定义的处理逻辑过滤器:遵循AOP(面向切面编程)思想实现,基于Servlet规范提供的Filter接口,它是位于客户端请求与服务器响应之间的一个组件,依赖于Servlet容器。当......
  • java springboot拦截器的实现及用法
     1.前景,有时候我们在不同的地方需要使用用户的信息,我们可以使用threadLocal存储信息,这样我们在在这个线程随时使用用户信息了,不用自己在写一段冗余代码了,这时候使用拦截器就很不错 2.实现1.实现HandlerInterceptor2.重写实现方法  preHandle:在业务处理器处理请......
  • SpringMVC声明式事务
    事务并发、传播性、隔离级别(重难点)导读:本节重点在于多线程并发环境下的事务处理、和数据库在并发环境下的表锁和行锁。案例:在新增图书的时候,肯定需要先新增作者。SpringMVC声明式事务事务分两种:编程式事务、声明式事务Connectionconnconn.setAutoCommit(false)conn.comm......
  • SpringMVC实现文件上传&下载(2)
    文件上传步骤第一步:由于SpringMVC使用的是commons-fileupload实现,故将其组件引入项目中,这里用到的是commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar。第二步:spring-mvx中配置MultipartResolver处理器。可在此加入对上传文件的属性限制。第三步:在Controller的方法中添加M......
  • spring - springmvc - @EnableCaching
    @EnableCaching@EnableCaching注释在应用程序中启用注释驱动的缓存管理功能,并允许我们在应用程序中使用@Cacheable和@CacheEvict注释。具有类似功能的XML等效项是cache:*命名空间:@Configuration@EnableCachingpublicclassCacheConfig{@BeanpublicCacheMana......
  • springMVC执行流程--
    springMVC执行流程1.springMVC执行流程Springmvc的执行流程是这个框架最核心的内容视图阶段(老旧JSP等)前后端分离阶段(接口开发,异步)2.视图阶段(jsp)重要的组件:前端控制器、处理器映射器、处理器适配器、视图解析器3.前后端分离阶段(接口开发,异步)4.问题总结......
  • (转)gRPC 拦截器
    原文:https://www.cnblogs.com/rickiyang/p/14975552.htmlGogRPC学习系列:跟我一起学Go系列:gRPC入门必备第一篇内容我们已经基本了解到gRPC如何使用、对应的三种流模式。现在已经可以让服务端和客户端互相发送消息。本篇仍然讲解功能性的使用说明:如何使用拦截器。使用过......
  • 黑马程序员JavaWeb学习笔记-拦截器
    拦截器--Interceptor--快速入门@Component注解交给ioc容器管理--注册配置拦截器@Configuration注解用来标识当前是Spring当中的一个配置类//Interceptor拦截所有("/**")//Filter拦截所有("/*")//WebConfig需要在包下新建一个config包与controller同级//.excl......
  • 关于SpringMVC中@RequestMapping的params参数
    @RequestMapping注解的params参数同一个url,只要params不同,springmvc也是会区分匹配的。@PostMapping("/reduceProductStock")publicStringreduceProductStock(@RequestParamLongproductId,@RequestParamIntegerquantity){productService.reduceProductStock(pr......