Interceptor/filter/listen
feign拦截器
RequestInterceptor:
- 在使用feign做服务间调用的时候,如何修改请求的头部或编码信息呢,可以通过实现RequestInterceptor接口的apply方法,feign在发送请求之前都会调用该接口的apply方法,所以我们也可以通过实现该接口来记录请求发出去的时间点。
- RequestInterceptor接口定义了apply方法,其参数为RequestTemplate;它有一个抽象类为BaseRequestInterceptor,还有几个实现类分别为BasicAuthRequestInterceptor、FeignAcceptGzipEncodingInterceptor、FeignContentGzipEncodingInterceptor
gateway过滤器
AbstractGatewayFilterFactory:
- 局部过滤
GlobalFilter:
- 全局过滤
Ordered:
- 拦截器扫描顺序
Spring监听器
ApplicationEventPublisher:
- 业务场景:当用户注册后,发送邮件到其邮箱提示用户进行账号激活,且注册成功的同时需要赠送新人用户体验卡券。
SpringMVC拦截器
HandlerInterceptor:
preHandle
调用时间:Controller方法处理之前
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行
若返回false,则中断执行,注意:不会进入afterCompletion
postHandle
调用前提:preHandle返回true
调用时间:Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒着执行。
备注:postHandle虽然post打头,但post、get方法都能处理
afterCompletion
调用前提:preHandle返回true
调用时间:DispatcherServlet进行视图的渲染之后
多用于清理资源
RequestContextHolder:
在实际开发中:如果想在Service
层或者某个工具类层里获取HttpServletRequest、HttpServletResponse
对象,其中一种方式是,把request/response当作入参,一层一层的传递下去。不过这种有点费劲,且做起来很不优雅。这里介绍另外一种方案:RequestContextHolder
,任意地方使用如下代码:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
RequestContextHolder顾名思义,持有上下文的Request容器.使用是很简单的,它所有方法都是static
的。
Springboot拦截器
WebMvcConfigurer
WebMvcConfigurer接口常用的方法:
/**拦截器配置**/ void addInterceptors(InterceptorRegistry var1); /**视图跳转控制器**/ void addViewControllers(ViewControllerRegistry registry); /**静态资源处理**/ void addResourceHandlers(ResourceHandlerRegistry registry); /**默认静态资源处理器**/ void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer); /**这里配置视图解析器**/ void configureViewResolvers(ViewResolverRegistry registry); /**配置内容裁决的一些选项&*/ void configureContentNegotiation(ContentNegotiationConfigurer configurer); /**解决跨域问题**/ public void addCorsMappings(CorsRegistry registry) ; /**添加类型转换器和格式化器**/ void addFormatters(FormatterRegistry registry); /**在springmvc和springboot中,均默认采用MappingJackson2HttpMessageConverter来实现JSON数据的处理, 可以通过这个方法用其他转换器实现 比如:GsonHttpMessageConverter**/ void extendMessageConverters(List<HttpMessageConverter<?>> converters); /**自定义参数解析器**/ void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers)
addInterceptors:拦截器
addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截
excludePathPatterns:用于设置不需要拦截的过滤规则
拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。
@Override public void addInterceptors(InterceptorRegistry registry) { super.addInterceptors(registry); registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**").excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**"); }
addViewControllers:页面跳转
以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurer中的addViewControllers方法即可达到效果了
@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/toLogin").setViewName("login"); }
addResourceHandlers:静态资源
比如,我们想自定义静态资源映射目录的话,只需重写addResourceHandlers方法即可。
@Configuration public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer { /** * 配置静态访问资源 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/my/**").addResourceLocations("classpath:/my/"); } }
addResoureHandler:指的是对外暴露的访问路径
addResourceLocations:指的是内部文件放置的目录
configureViewResolvers:视图解析器
这个方法是用来配置视图解析器的,该方法的参数ViewResolverRegistry 是一个注册器,用来注册你想自定义的视图解析器等。
/** * 配置请求视图映射 * @return */ @Bean public InternalResourceViewResolver resourceViewResolver() { InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); //请求视图文件的前缀地址 internalResourceViewResolver.setPrefix("/WEB-INF/jsp/"); //请求视图文件的后缀 internalResourceViewResolver.setSuffix(".jsp"); return internalResourceViewResolver; } /** * 视图配置 * @param registry */ @Override public void configureViewResolvers(ViewResolverRegistry registry) { super.configureViewResolvers(registry); registry.viewResolver(resourceViewResolver()); /*registry.jsp("/WEB-INF/jsp/",".jsp");*/ }
addCorsMappings:跨域
@Override public void addCorsMappings(CorsRegistry registry) { super.addCorsMappings(registry); registry.addMapping("/cors/**") .allowedHeaders("*") .allowedMethods("POST","GET") .allowedOrigins("*"); }
configureMessageConverters:信息转换器
/** * 消息内容转换配置 * 配置fastJson返回json转换 * @param converters */ @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { //调用父类的配置 super.configureMessageConverters(converters); //创建fastJson消息转换器 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); //创建配置类 FastJsonConfig fastJsonConfig = new FastJsonConfig(); //修改配置返回内容的过滤 fastJsonConfig.setSerializerFeatures( SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty ); fastConverter.setFastJsonConfig(fastJsonConfig); //将fastjson添加到视图消息转换器列表内 converters.add(fastConverter); }