SpringBoot 2.0 配置拦截器

本文介绍了SpringBoot 2.0中如何配置拦截器,包括自定义拦截器的创建(实现HandlerInterceptor接口和继承HandlerInterceptorAdapter),注册拦截器的步骤,以及测试Controller的编写。通过示例展示了拦截器的执行顺序:前置拦截 -> 业务处理 -> 后置拦截 -> 末置拦截,并讨论了多个拦截器的执行顺序遵循先进后出原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拦截器常见应用场景

日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;

性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。

OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。

…………本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。

自定义拦截器

(1)Pom.xml 

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <!-- springboot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    <dependencies>

(2)自定义一个拦截器,有两种创建方式,我们用这两种方式分别建一个拦截器,如下

实现HandlerInterceptor 拦截器接口

package com.zx.demo.Interceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;

@Component
public class Interceptor1 implements HandlerInterceptor {
	
	private Logger log = LoggerFactory.getLogger(this.getClass());
	//前置处理:controller处理前调用,可以做一些参数预处理、登录校验等,true继续执行,false不再做下面的任何处理了
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		log.info("Interceptor1前置处理-----------------------");
		return true;
	}

	//后置处理:controller执行后,视图渲染前
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		log.info("Interceptor1后置处理-----------------------");
	}

	//末置处理: controller执行完,视图也渲染完成,整个请求结束返回前,可以做:资源的清空、整个请求处理时长等
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		log.info("Interceptor1末置处理-----------------------");
	}
}

继承HandlerInterceptorAdapter适配器类 

package com.zx.demo.Interceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class Interceptor2 extends HandlerInterceptorAdapter {
	
	private Logger log = LoggerFactory.getLogger(this.getClass());
	//前置处理:controller处理前调用,可以做一些参数预处理、登录校验等,true继续执行,false不再做下面的任何处理了
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		log.info("Interceptor2前置处理-----------------------");
		return true;
	}

	//后置处理:controller执行后,视图渲染前
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		log.info("Interceptor2后置处理-----------------------");
	}

	//末置处理: controller执行完,视图也渲染完成,整个请求结束返回前,可以做:资源的清空、整个请求处理时长等
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		log.info("Interceptor2末置处理-----------------------");
	}
}

(3)注册拦截器

package com.zx.demo.config;
import com.zx.demo.Interceptor.Interceptor1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfigurer implements WebMvcConfigurer{
	
	  @Autowired
	  private Interceptor1 interceptor1;
	  // 这个方法是用来配置静态资源的,比如html,js,css,等等
	  @Override
	  public void addResourceHandlers(ResourceHandlerRegistry registry) {
	
	  }

	  // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
	  @Override
	  public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(interceptor1);
	  }
}

(4)编写测试Controller

package com.zx.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    Logger log = LoggerFactory.getLogger(HelloController.class);

    @RequestMapping("/sayHello")
    public String sayHello(){
        log.info("sayHello接口调用---------------");
        return "hello test!";
    }
}

 (5)启动类

package com.zx.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(DemoApplication.class);
	}
}

右键启动类启动项目后,浏览器访问localhost:9090/sayHello接口,控制台输出效果:

 可以清晰的看到拦截器中配置的三个方法以及我们的接口处理顺序: 前置拦截器 --->  业务处理  --->  后置拦截器  --->末置拦截器

因为我在webConfigure中只注入了拦截器1,所以只打印了拦截器1的数据。我们把拦截器2也注入进去,修改(3)步骤

package com.zx.demo.config;
import com.zx.demo.Interceptor.Interceptor1;
import com.zx.demo.Interceptor.Interceptor2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfigurer implements WebMvcConfigurer{
	
	  @Autowired
	  private Interceptor1 interceptor1;
	  @Autowired
	  private Interceptor2 interceptor2;
	  
	// 这个方法是用来配置静态资源的,比如html,js,css,等等
	  @Override
	  public void addResourceHandlers(ResourceHandlerRegistry registry) {
	  }
	 
	  // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
	  @Override
	  public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(interceptor1);
		registry.addInterceptor(interceptor2);
	  }
}

运行结果:

拦截器拦截处理执行顺序是: 前置--- >   业务处理  ---->   后置  --->  末置 

多个拦截器执行顺序,根据addInterceptor注入的先后顺序,针对每一步的多个拦截操作执行顺序是先进后出原则

 

 

 

 
Spring Boot 2.0中,要拦截并处理TRACE请求以防止敏感信息泄露,你可以自定义一个WebMvcConfigurer或创建一个Filter。这里是一个简单的步骤说明: 1. **使用WebMvcConfigurer**: 首先,你需要创建一个实现了`WebMvcConfigurer`接口的类,并覆盖`addInterceptors()`方法来添加一个全局Interceptor。 ```java 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 TraceRequestInterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new TraceRequestFilter()) .addPathPatterns("/**") // 匹配所有路径 .excludePathPatterns("/api/private"); // 可选,排除不需要拦截的路径 } } ``` 然后创建一个`TraceRequestFilter`类,检查是否为TRACE请求,如果是,则修改请求头。 ```java import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class TraceRequestFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; if ("TRACE".equals(httpRequest.getMethod())) { handleTraceRequest(httpRequest); // 处理 TRACE 请求 } else { chain.doFilter(request, response); } } private void handleTraceRequest(HttpServletRequest request) { // 对HEAD、OPTIONS等安全的HTTP方法保持原样,其他方法如TRACE将替换为GET或POST String newMethod = "GET"; // 或者 POST request.setRequestMethod(newMethod); // 修改请求头,去掉可能暴露敏感信息的部分 // 示例:只保留User-Agent,移除其他头 request.getHeaderNames().forEach(name -> { if (!"User-Agent".equalsIgnoreCase(name)) { request.removeHeader(name); } }); } // 其他方法... } ``` 2. **使用Filter**: 如果你想使用Filter而不是配置,可以创建一个单独的类并注册它。 ```java import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class TraceRequestFilter implements Filter { // ...同上 @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { // ...同上 } } ``` 别忘了在`web.xml`或`application.properties`中添加过滤器配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值