1. Introduce pom dependency
- Because almost all web projects use the interceptor, the interceptor object introduced into the next web package is also in the web package
- thymeleaf: view the static interface;
<!--introduce springboot Parent project dependency-->
<!--Introduce dependency:
It can be omitted version Tag to get some reasonable default configuration
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<dependencies>
<!--Introduction contains WebMvcConfigurer My bag-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--template engine -Used to view the interface-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
2. Startup class configuration
- Just note that other classes should be in the same package or lower directory of the startup class, so that @ ComponentScan can scan in @ SpringBootApplication;
- If the class is not in the same level directory or lower level directory, it can be imported with @ Import(Xxx.class);
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/*HandlerInterceptor Startup class*/
@SpringBootApplication
public class InterceptorTestAppliction {
public static void main(String[] args) {
SpringApplication.run(InterceptorTestAppliction.class, args);
}
}
3. Data under resources package
- It mainly tests several corresponding functions of the interceptor, and their contents are not important;
4.HandlerInterceptor custom interceptor instance configuration
- The running order of the three methods is: prehandle - > posthandle - > aftercompletion;
- If the return value of preHandle is false, the three methods only run preHandle;
- If there is an error in running the code after interception and release, postHandle will not be executed;
- The custom interceptor instance needs to implement the HandleInterceptor interface;
- The interceptor instance needs to be used to inject custom interceptor configuration into ioc;
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;
//custom interceptor
//The custom interceptor needs to implement the HandleInterceptor interface
@Component
public class MyInterceptor implements HandlerInterceptor {
//Execute before processor runs
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("Pre run----a1");
//A return value of false will intercept the operation of the original processor
//If multiple interceptors are configured, the return value of false will terminate the operation of the interceptors configured behind the current interceptor
System.out.println(handler);
return true;
}
//Execute after processor runs
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("Post run----b1");
System.out.println(handler);
System.out.println(modelAndView);
}
//After the post execution of all interceptors is completed, execute the operation
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("Complete run----c1");
System.out.println(handler);
System.out.println(ex);
}
//The running order of the three methods is prehandle - > posthandle - > aftercompletion
//If the return value of preHandle is false, the three methods only run preHandle
}
5.WebMvcConfigurer custom interceptor configuration
- WebMvcConfigurer is an interface that provides, for example, cross domain settings, custom interceptors, type converters, and so on
- In terms of cross domain, I don't intend to use interceptors as filters for gateways. Let's broaden our thinking here. Interceptors can also be set across domains
5.1 enable and register custom interceptor instances
- Obtain the interceptor instance from ioc and pass the interceptor as an input parameter into InterceptorRegistry();
- Be sure to specify interceptor path and exclude interception path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
//custom interceptor
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Autowired //Inject the custom interceptor instance you wrote into it
private MyInterceptor myInterceptor;
// This method is used to register interceptors. Interceptors written by ourselves need to be registered here to take effect
@Override
public void addInterceptors(InterceptorRegistry registry) {
//Create an InterceptorRegistration object and pass in a custom interceptor;
InterceptorRegistration interceptorRegistration = registry.addInterceptor(myInterceptor);
//addPathPatterns method (specify the interception path, often using "/ * *")
interceptorRegistration.addPathPatterns("/**");
//Bean There is a sequence when loading, and the default is 0 and @ Order(0)
interceptorRegistration.order(0);
//excludePathPatterns Method (specify the exclusive interception path, which is used for login and other open interfaces)
interceptorRegistration.excludePathPatterns("/mhh/Interceptor/excludeInterceptorTest");
/**
* The path matcher implementation used with this interceptor.
* This is an optional high-level property that is only required when implemented using a custom path matcher,
* The implementation supports mapping metadata, but the Ant path pattern is not supported by default.
*/
// interceptorRegistration.pathMatcher(new PathMatcher() {
// @Override
// public boolean isPattern(String s) {
// return false;
// }
//
// @Override
// public boolean match(String s, String s1) {
// return false;
// }
//
// @Override
// public boolean matchStart(String s, String s1) {
// return false;
// }
//
// @Override
// public String extractPathWithinPattern(String s, String s1) {
// return null;
// }
//
// @Override
// public Map<String, String> extractUriTemplateVariables(String s, String s1) {
// return null;
// }
//
// @Override
// public Comparator<String> getPatternComparator(String s) {
// return null;
// }
//
// @Override
// public String combine(String s, String s1) {
// return null;
// }
// });
// registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/register");
}
}
5.11 interceptor test
- Normal access – interceptorTest: enter the interceptor – preHandle() – > enter the method to be accessed – interceptorTest() – > enter the interceptor – postHandle() – > enter the interceptor – afterCompletion – > return to the page;
- Exclude – excludeInterceptorTest: it will not enter the interceptor normally - > and then return;
- Code error access – exceptionTest: enter the interceptor – preHandle() – > enter the method to access – exceptionTest() – > code error – > enter the interceptor – afterCompletion – > return to the page (it will not go through the interceptor postHandle() method)
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/mhh/interceptor")
public class InterceptorTestController {
@RequestMapping("interceptorTest/{id}")
public String InterceptorTest(@PathVariable("id") String docId){
return docId;
}
@RequestMapping("excludeInterceptorTest")
public String excludeInterceptorTest(){
return "Exclusion test";
}
@RequestMapping("exceptionTest")
public void exceptionTest(){
throw new RuntimeException("Test exception error");
}
}
5.2 user defined resource mapping
- classpath: indicates the absolute directory of the project
- file: indicates the local absolute directory
- The mapping path must end with:/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
//custom interceptor
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
// Custom resource mapping
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Add a static resource path, and then map it to the path of the project
//addResourceHandler adds a mapping path for.
//addResourceLocations adds a resource path for.
//file: indicates the local absolute directory
registry.addResourceHandler("/mhh/interceptor/document/*").addResourceLocations("file:///D:/doc/");
//addResourceHandler adds a mapping path for.
//addResourceLocations adds a resource path for.
//classpath: indicates the absolute directory of the project
registry.addResourceHandler("/mhh/interceptor/js/*").addResourceLocations("classpath:static/js/");
}
}
5.21 custom resource mapping test
- file: indicates the local absolute directory
- It can be seen that: http://localhost:8080/mhh/interceptor/document/aa.png
Mapped are: D:/doc/aa.png
- classpath: indicates the relative directory of the project
- It can be seen that: http://localhost:8080/mhh/interceptor/js/jquery.js
The actual access is: static/js/jquery.js
5.3 automatically jump to a page through the path
- This method can realize that a path automatically jumps to a page
- This is equivalent to using the new ModelAndView("login") method to jump
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
//custom interceptor
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/goToLogin").setViewName("login");
}
}
5.31 automatic jump to a page test through path
- First, jump to find the specified page through ModelAndView
- Jump through interceptor addViewControllers
5.4 addcorsmapping (corsregistry Registry) setting cross domain
- It mainly solves the cross domain problem (or it is recommended to configure the CorsWebFilter instance in the gateway for the cross domain problem)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
//custom interceptor
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
//To set cross domain issues, it is best to configure corswebfilter CORS when using the gateway
@Override
public void addCorsMappings(CorsRegistry registry) {
//Add mapping paths, "/ * *", which means that global cross domain access permissions are set for all paths
CorsRegistration corsRegistration = registry.addMapping("/**");
//Which ip or domain names are allowed to be accessed across domains * means yes, so do not write *, otherwise the cookie will not be used (it is recommended not to use *, * means that all requests are allowed to be accessed across domains, please drink tea by the security department)
corsRegistration.allowedOrigins("*");
//Send Cookie information
corsRegistration.allowCredentials(true);
//Allowed request mode
corsRegistration.allowedMethods("GET", "POST", "DELETE", "PUT");
//Indicates which Header information is allowed to be carried in the access request, such as Accept, Accept language, content language and content type
corsRegistration.allowedHeaders("*");
//Which header information is exposed (because cross domain access cannot obtain all header information by default)
corsRegistration.exposedHeaders(HttpHeaders.CONTENT_DISPOSITION);
//Set the waiting time, 1800 seconds by default
corsRegistration.maxAge(3600);
}
}
5.5 addformatters (formatterregistry) data formatter configuration
- Inject your own set date formatting instance DateFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
//custom interceptor
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Autowired
private DateFormatter dateFormatter;
//Add a data formatter by overriding the addFormatters method.
// When Spring MVC accepts HTTP requests, it will automatically bind and map parameters to Controller request parameters.
// There is no default configuration in Spring to convert strings to date types.
// In this case, the automatic conversion can be realized by adding a DateFormatter class.
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(dateFormatter);
}
}
5.51 first implement the format configuration instance (here, the date is used as the instance)
- It is used to accept HTTP requests and automatically bind and map date parameters to Controller request parameters
- There is no default configuration in Spring to convert strings to date types.
- The date type template here is the key point, which is used to indicate how the foreground transfers values.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;
@Component
public class DateFormatter implements Formatter<Date> {
// Date type template: e.g. yyyy MM DD
private String datePattern="yyyy-MM-dd";
// Date formatting object
private SimpleDateFormat dateFormat;
// Constructor to create a date format object by relying on the injected date type
public DateFormatter(/*String datePattern*/) {
// this.datePattern=datePattern;
this.dateFormat = new SimpleDateFormat(datePattern);
}
// Displays T-type objects with formatter < T >
public String print(Date date,Locale locale){
return dateFormat.format(date);
}
// Parsing a text string returns a T-type object with formatter < T >.
public Date parse(String source, Locale locale) throws ParseException {
try {
return dateFormat.parse(source);
} catch (Exception e) {
throw new IllegalArgumentException();
}
}
}
5.52 data formatter configuration test
- Front end parameter transmission inlet
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Date;
@RestController
@RequestMapping("/mhh/interceptor")
public class InterceptorTestController {
@GetMapping("getDate")
public Date getDate(@RequestParam("date") Date date) {
return date;
}
}
- Note that the format of parameter transfer should correspond to the date type template