Detailed explanation of common use of WebMvcConfigurer interceptor of SpringBoot

Keywords: Java Spring Boot

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








Link: Common use of WebMvcConfigurer interceptor of SpringBoot detailed source code download address

Posted by Zemnon on Sat, 23 Oct 2021 01:16:53 -0700