custom interceptor
HandlerInterceptorAdapter,HandlerInterceptor
- HandlerInterceptorAdapter needs to inherit and HandlerInterceptor needs to be implemented
- It can be used as logging and login verification
- It is recommended to use HandlerInterceptorAdapter because methods can be overridden on demand.
There are three main methods:
- preHandle: intercepts and judges when the request just enters. It needs a boolean return value. If it returns true, it will continue to execute. If it returns false, it will not execute. It is generally used for login verification.
- postHandle: after the interception method returns successfully, you can operate modelAndView before rendering the view.
- After completion: after the method returns successfully, the log record of the successful return can be made before the view is rendered.
Sometimes we only need to implement one of the three callback methods. If we implement the HandlerInterceptor interface, the three methods must be implemented. Whether you need it or not, spring provides a HandlerInterceptorAdapter adapter (an implementation of adapter design model), which allows us to implement only the required callback methods.
In this way, in our business, for example, we need to record the system log. The log must be recorded after afterCompletion, otherwise it will be bullshit if it fails halfway. After the program runs normally, we record the operation logs of adding, deleting and changing the database into the database. Therefore, we only need to inherit the HandlerInterceptorAdapter and override the afterCompletion method, because the preHandle is true by default.
The operation process is summarized as follows:
- The interceptor execution order depends on the order defined in the Spring configuration file.
- The preHandle methods of all interceptors will be executed in order until return false is encountered. For example, if the second preHandle method is return false, the third and all future interceptors will not be executed. If both return true, the preHandle methods will be loaded sequentially.
- Then execute the main method (its own controller interface). If an exception is thrown in the middle, the effect is the same as return false. The postHandle will not be executed, but the afterCompletion method will be executed in reverse order.
- When the main method finishes executing the business logic (the page has not rendered data), execute the postHandle method in reverse order. If the preHandle method of the third interceptor returns false, the second and first postHandle methods and afterCompletion methods will be executed (this method will not be executed until the postHandle is executed, that is, after the data is rendered on the page)( postHandle and afterCompletion are executed in reverse order)
Configuring Interceptors
Customize WebMvcConfig, implement WebMvcConfigurer, and duplicate addinterceptors (interceptor Registry) method to configure interceptors.
WebMvcConfigurer
WebMvcConfigurer configuration class is actually a configuration method within Spring. It uses JavaBean instead of the traditional xml configuration file to customize the framework. You can customize some handlers, interceptors, viewresolvers and messageconverters. For spring mvc configuration based on Java based mode, you need to create a configuration class and implement the WebMvcConfigurer interface.
In spring boot version 1.5, the method of rewriting WebMvcConfigurerAdapter is used to add custom interceptors, message converters, etc. After SpringBoot 2.0, this class is marked @ Deprecated. It is officially recommended to directly implement WebMvcConfigurer or directly inherit WebMvcConfigurationSupport. Method 1 implements the WebMvcConfigurer interface (recommended), and method 2 inherits the WebMvcConfigurationSupport class.
See this article for specific implementation: https://blog.csdn.net/fmwind/article/details/82832758
WebMvcConfigurer interface
public interface WebMvcConfigurer { void configurePathMatch(PathMatchConfigurer var1); void configureContentNegotiation(ContentNegotiationConfigurer var1); void configureAsyncSupport(AsyncSupportConfigurer var1); void configureDefaultServletHandling(DefaultServletHandlerConfigurer var1); void addFormatters(FormatterRegistry var1); void addInterceptors(InterceptorRegistry var1); void addResourceHandlers(ResourceHandlerRegistry var1); void addCorsMappings(CorsRegistry var1); void addViewControllers(ViewControllerRegistry var1); void configureViewResolvers(ViewResolverRegistry var1); void addArgumentResolvers(List<HandlerMethodArgumentResolver> var1); void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> var1); void configureMessageConverters(List<HttpMessageConverter<?>> var1); void extendMessageConverters(List<HttpMessageConverter<?>> var1); void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> var1); void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> var1); Validator getValidator(); MessageCodesResolver getMessageCodesResolver(); }
common method
/* Interceptor configuration */ void addInterceptors(InterceptorRegistry var1); /* View jump controller */ void addViewControllers(ViewControllerRegistry registry); /** Resource processing**/ void addResourceHandlers(ResourceHandlerRegistry registry); /* Default static resource processor */ void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer); /** The view parser is configured here**/ void configureViewResolvers(ViewResolverRegistry registry); /* Some options for configuring content arbitration*/ void configureContentNegotiation(ContentNegotiationConfigurer configurer); /** Solve cross domain problems**/ public void addCorsMappings(CorsRegistry registry) ;
addInterceptors: interceptors
addInterceptor: you need an interceptor instance that implements the HandlerInterceptor interface
addPathPatterns: used to set the filter path rules of the interceptor; addPathPatterns("/ * *") intercepts all requests
excludePathPatterns: used to set filtering rules that do not need to be intercepted
The interceptor is mainly used to intercept user login status, log, etc.
@Override public void addInterceptors(InterceptorRegistry registry) { super.addInterceptors(registry); registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**").excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**"); }
addViewControllers: page Jump
In the past, when writing spring MVC, if you need to access a page, you must write the Controller class, and then write a method to jump to the page. It feels troublesome. In fact, you can achieve the effect by rewriting the addViewControllers method in WebMvcConfigurer
@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/toLogin").setViewName("login"); }
The value indicates that rewriting the addViewControllers method here will not overwrite the addViewControllers in webmvcaitoconfiguration (in this method, Spring Boot maps "/" to index.html), which means that its own configuration is effective at the same time as the automatic configuration of Spring Boot, This is also the way we recommend adding our own MVC configuration.
addResourceHandlers: static resources
For example, if we want to customize the static resource mapping directory, we just need to override the addResourceHandlers method.
Note: if you inherit the WebMvcConfigurationSupport class, you must override this method when implementing configuration. See other articles for details
@Configuration public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer { /** * Configure static access resources * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/my/**").addResourceLocations("classpath:/my/"); } }
Addresourcehandler: refers to the exposed access path
addResourceLocations: refers to the directory where internal files are placed
Configuredefault servlethandling: the default static resource handler
@Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); configurer.enable("defaultServletName"); }
At this time, a default Handler will be registered: DefaultServletHttpRequestHandler, which is also used to process static files. It will try to map /. When dispatcherservert maps / and / and no suitable Handler is found to handle the request, it will be handed over to DefaultServletHttpRequestHandler for processing. Note: the static resources here are placed in the web root directory, not in the WEB-INF directory.
For example, there is a picture in the webroot Directory: 1.png we know that the files in the web root directory (webroot) in the Servlet specification can be accessed directly, but because the dispatcher Servlet is configured with a mapping path of: /, it intercepts almost all requests, resulting in the inaccessibility of 1.png, At this time, registering a DefaultServletHttpRequestHandler can solve this problem. In fact, it can be understood that dispatcher Servlet destroys a feature of Servlet (files in the root directory can be accessed directly). DefaultServletHttpRequestHandler helps to return this feature.
configureViewResolvers: View resolver
This method is used to configure the view parser. The parameter ViewResolverRegistry of this method is a registrar, which is used to register the view parser you want to customize, etc. Several common methods of ViewResolverRegistry: https://blog.csdn.net/fmwind/article/details/81235401
/** * Configure request view mapping * @return */ @Bean public InternalResourceViewResolver resourceViewResolver() { InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); //Prefix address of the requested view file internalResourceViewResolver.setPrefix("/WEB-INF/jsp/"); //Suffix of the requested view file internalResourceViewResolver.setSuffix(".jsp"); return internalResourceViewResolver; } /** * View configuration * @param registry */ @Override public void configureViewResolvers(ViewResolverRegistry registry) { super.configureViewResolvers(registry); registry.viewResolver(resourceViewResolver()); /*registry.jsp("/WEB-INF/jsp/",".jsp");*/ }
Configurecontent Negotiation: configure some parameters of content arbitration
addCorsMappings: cross domain
@Override public void addCorsMappings(CorsRegistry registry) { super.addCorsMappings(registry); registry.addMapping("/cors/**") .allowedHeaders("*") .allowedMethods("POST","GET") .allowedOrigins("*"); }
configureMessageConverters: information converters
/** * Message content conversion configuration * Configure fastJson to return json transformation * @param converters */ @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { //Call the configuration of the parent class super.configureMessageConverters(converters); //Create fastjason message converter FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); //Create configuration class FastJsonConfig fastJsonConfig = new FastJsonConfig(); //Modify the filtering of the returned content of the configuration fastJsonConfig.setSerializerFeatures( SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty ); fastConverter.setFastJsonConfig(fastJsonConfig); //Add fastjson to the list of view message converters converters.add(fastConverter); }