spring-boot - 如何在 Spring Boot 中仅使用一个拦截器处理所有传入请求
问题描述
我从几天开始一直在做spring boot,现在我想对所有传入的请求都有安全拦截器。在学习教程时,我发现有一个带有@Component
注释的类,它实现HandlerInterceptor
@Component
public class ProductServiceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) throws Exception {}
}
然后必须InterceptorRegistry
使用WebMvcConfigurerAdapter
like注册此拦截器
@Component
public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter {
@Autowired
ProductServiceInterceptor productServiceInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(productServiceInterceptor);
}
}
但我在本教程中感到困惑,拦截器仅用于一项服务,即Products
,我的问题是如何拥有一个single interceptor class which will intercept all the incoming requests irrespective of any controller path
解决方案
如果您想保护您的应用程序,您可能需要查看Spring Security项目。
要实现您想要做的事情,您需要使用Filter和FilterRegistrationBean。
过滤器将拦截来自您在注册 bean 中定义的路径的每个请求和响应。
从过滤器javadoc:
每次由于客户端对链末端资源的请求,请求/响应对通过链时,容器都会调用 Filter 的 doFilter 方法。传入此方法的 FilterChain 允许 Filter 将请求和响应传递给链中的下一个实体。此方法的典型实现将遵循以下模式:
- 检查请求
- 可以选择使用自定义实现包装请求对象以过滤内容或标题以进行输入过滤
- 可以选择使用自定义实现包装响应对象以过滤内容或标题以进行输出过滤
- a) 使用 FilterChain 对象 (chain.doFilter()) 调用链中的下一个实体,
- b) 或不将请求/响应对传递给过滤器链中的下一个实体以阻止请求处理
- 调用过滤器链中的下一个实体后,直接在响应上设置标头。
下面是一个过滤来自根 ("/*") 路径的所有请求的示例。
package com.example.demo;
import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
private static final Logger log = LoggerFactory.getLogger(FilterConfig.class);
@Bean
public FilterRegistrationBean<Filter> registrationBean(Filter sampleFilter) {
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter(sampleFilter);
bean.addUrlPatterns("/*");
return bean;
}
@Bean
public Filter sampleFilter() {
return (request, response, filterChain) -> {
HttpServletRequest servletRequest = (HttpServletRequest) request;
log.info(
"Request URI : {}",
servletRequest.getRequestURI());
filterChain.doFilter(request, response);
log.info(
"After filtering the request : {}",
servletRequest.getRequestURI());
};
}
}
推荐阅读
- python-3.x - 如何使用 Python Ray 在不耗尽内存的情况下并行处理大量数据?
- css - 动画固定元素到视口的中心
- powershell - GUI-button to exit loop, Move-Item Job
- android - Flutter Scaffold 允许子系统 Navigation Bar 后面
- php - 如何在 PHP 中为验证码生成添加失真和编辑字体?
- git - Git Checkout - npm run watch - 没有任何改变
- angular - Angular 6:如果“无法匹配任何路线”移动到其他组件
- android - 对于语言环境“ar”(阿拉伯语),还应定义以下数量:少、多、二、零
- gcloud - Cloud ML Engine 无法在命令行中运行,并说找不到有效的 Python 路径
- reactjs - 尝试上传到 s3 时出现“params.Body is required”错误