1. Interceptors
The Interceptor interceptor in Springboot, also known as the interceptor in mvc, omits the xml configuration section.There is no essential difference, all through the implementation of several methods in HandlerInterceptor.The functions of several methods are listed below.
-
preHandle
Executed before entering the Habdler method, commonly used for authentication authorization, etc. -
postHandle
Executed before returning to modelAndView after entering the Handler method, typically used to insert public model data, and so on. -
afterCompletion
Final processing, commonly used for log collection, unified follow-up processing, and so on.
1.1 Introducing dependencies
<!-- Spring Boot web Development Integration --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>spring-boot-starter-json</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Ali fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!-- Lombok tool --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- Import Profile Processor, in Configuration springboot Relevant files will be prompted --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <!-- unit testing --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency>
1.2 Writing interceptors
package net.codingme.boot.config; import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * <p> * Interceptor * * @Author niujinpeng * @Date 2019/1/6 16:54 */ @Slf4j public class LogHandlerInterceptor implements HandlerInterceptor { /** * Before the request method executes * Returning true passes through * * @param request * @param response * @param handler * @return */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { StringBuffer requestURL = request.getRequestURL(); log.info("preHandle request URL: " + requestURL.toString()); return true; } /** * Execute before returning to modelAndView * @param request * @param response * @param handler * @param modelAndView */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { log.info("postHandle Return modelAndView before"); } /** * Execute Handler to complete execution of this method * @param request * @param response * @param handler * @param ex */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { log.info("afterCompletion After executing the request method and returning completely"); } }
1.3 Configure Interceptors
After omitting the interceptor configuration section in the XML, configure the custom interceptor in the way recommended by springboot.
package net.codingme.boot.config; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.ArrayList; import java.util.List; /** * <p> * 1.Use FastJSON * 2.Configure Time Formatting * 3.Solve Chinese garbles * 4.Add Custom Interceptor * * @Author niujinpeng * @Date 2018/12/13 15:35 */ @Configuration public class WebMvcConfig implements WebMvcConfigurer { /** * Custom JSON Converter * * @param converters */ @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat); //DateFormatter fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); //Handling Chinese scrambling List<MediaType> fastMediaTypes = new ArrayList<>(); fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); converter.setSupportedMediaTypes(fastMediaTypes); converter.setFastJsonConfig(fastJsonConfig); converters.add(converter); } /** * Add Custom Interceptor * .addPathPatterns("/**") Intercepted Request Path * .excludePathPatterns("/user"); Excluded Request Path * * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LogHandlerInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/user"); } }
2 Section Programming
- AOP: Aspect-oriented programming without modifying source code implementation for extended functionality
- AOP takes the horizontal extraction mechanism instead of the traditional vertical inheritance system repetitive codes
- AOP underlying implementation using dynamic proxy
- Use dynamic proxy to create interfaces to implement class proxy objects when there is an interface
- Use dynamic proxy to create subclass proxy objects of classes without interfaces
import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; /** * <p> * Use AOP to record access logs * Use @Before to cut in at the beginning of the entry point * Use @After to cut in at the end of the entry point * Use @AfterReturning to cut in after the entry point return content (which can be used to do some processing on processing return values) * Use @Around to cut into content before and after the entry point and control when to execute the entry point's own content * Use @AfterThrowing for handling logic after an exception is thrown in the cut-in content section * <p> * Notes: * Aspect:AOP * Component: Bean * Slf4j: Log output log can be used directly * Order: When multiple AOP s cut into the same method, the smaller the priority, the higher the priority. * Actions before entry point, from small to large by order value * Operation after entry point, from large to small by order value * * @Author niujinpeng * @Date 2019/1/4 23:29 */ @Aspect @Component @Slf4j @Order(1) public class LogAspect { /** * Thread Storage Information */ ThreadLocal<Long> startTime = new ThreadLocal<>(); /** * Define entry points * First*: Identify all return types * Letter Path: Package Path * Two points.: current package and subpackage * Second*: All classes * Third*: All methods * The last two points: all types of parameters */ @Pointcut("execution(public * net.codingme.boot.controller..*.*(..))") public void webLog() { } /** * Cut in at the beginning of the entry point * * @param joinPoint */ @Before("webLog()") public void doBefore(JoinPoint joinPoint) { // Record request time startTime.set(System.currentTimeMillis()); // Get Request Domain ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); // Record Request Content log.info("Aspect-URL: " + request.getRequestURI().toLowerCase()); log.info("Aspect-HTTP_METHOD: " + request.getMethod()); log.info("Aspect-IP: " + request.getRemoteAddr()); log.info("Aspect-REQUEST_METHOD: " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); log.info("Aspect-Args: " + Arrays.toString(joinPoint.getArgs())); } /** * Processing content after entry point */ @After("webLog()") public void doAfter() { } /** * Cut in after the entry point return content (can be used to do some processing on processing return values) */ @AfterReturning(returning = "ret", pointcut = "webLog()") public void doAfterReturning(Object ret) throws Throwable { log.info("Aspect-Response: " + ret); Long endTime = System.currentTimeMillis(); log.info("Aspect-SpeedTime: " + (endTime - startTime.get()) + "ms"); } }
Access log output for viewing interceptors and AOP s.
09:57:15.408 INFO 2836 --- [nio-8080-exec-1] n.c.boot.config.LogHandlerInterceptor : preHandle request URL: http://localhost:8080/ 09:57:15.413 INFO 2836 --- [nio-8080-exec-1] net.codingme.boot.config.LogAspect : Aspect-URL: / 09:57:15.413 INFO 2836 --- [nio-8080-exec-1] net.codingme.boot.config.LogAspect : Aspect-HTTP_METHOD: GET 09:57:15.413 INFO 2836 --- [nio-8080-exec-1] net.codingme.boot.config.LogAspect : Aspect-IP: 0:0:0:0:0:0:0:1 09:57:15.414 INFO 2836 --- [nio-8080-exec-1] net.codingme.boot.config.LogAspect : Aspect-REQUEST_METHOD: net.codingme.boot.controller.HelloController.index 09:57:15.415 INFO 2836 --- [nio-8080-exec-1] net.codingme.boot.config.LogAspect : Aspect-Args: [] 09:57:15.424 INFO 2836 --- [nio-8080-exec-1] net.codingme.boot.config.LogAspect : Aspect-Response: Greetings from Spring Boot!SpringBoot Is a spring application program 09:57:15.425 INFO 2836 --- [nio-8080-exec-1] net.codingme.boot.config.LogAspect : Aspect-SpeedTime: 12ms 09:57:15.436 INFO 2836 --- [nio-8080-exec-1] n.c.boot.config.LogHandlerInterceptor : postHandle Return modelAndView before 09:57:15.437 INFO 2836 --- [nio-8080-exec-1] n.c.boot.config.LogHandlerInterceptor : afterCompletion After executing the request method and returning completely
3. Servlet,Filter,Listener
Servlet, Filter, Listener are the core content of Java web, so how do you use them in Springboot?
3.1 Writing Servlet s
package net.codingme.boot.servlet; import lombok.extern.slf4j.Slf4j; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * <p> * @WebServlet(urlPatterns = "/myservlet") // Define access paths * @Author niujinpeng * @Date 2019/1/24 16:25 */ @Slf4j @WebServlet(urlPatterns = "/myservlet") public class MyServlet extends HttpServlet { @Override public void init() throws ServletException { log.info("Servlet Start Initialization"); super.init(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { log.info("Servlet Start processing GET Method"); PrintWriter writer = resp.getWriter(); writer.println("Hello Servlet"); writer.flush(); writer.close(); } @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } @Override public void destroy() { log.info("Servlet Start Destroying"); super.destroy(); } }
3.2 Write Filter
package net.codingme.boot.filter; import lombok.extern.slf4j.Slf4j; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; /** * <p> * * @Author niujinpeng * @Date 2019/1/24 16:35 */ @Slf4j @WebFilter(urlPatterns = "/*") public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { log.info("Interceptors begin to intercept"); filterChain.doFilter(request, response); } }
3.3 Write Listener
package net.codingme.boot.listener; import lombok.extern.slf4j.Slf4j; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * <p> * * @Author niujinpeng * @Date 2019/1/24 16:45 */ @Slf4j @WebListener public class MyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { log.info("Listener Start Initialization"); } @Override public void contextDestroyed(ServletContextEvent sce) { log.info("Listener Start Destroying"); } }
3.4 Add to Container
There are two ways to add to a container, the first using annotation scanning.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.ComponentScan; /** * @ServletComponentScan Scan Servlet,Filter,Listener to add to container */ @SpringBootApplication @ServletComponentScan public class BootApplication { public static void main(String[] args) { SpringApplication.run(BootApplication.class, args); } }
Or use a configuration class to add to the container.
/** * <p> * Register Servlet Filter Listener here or use @ServletComponentScan * * @Author niujinpeng * @Date 2019/1/24 16:30 */ @Configuration public class WebCoreConfig { @Bean public ServletRegistrationBean myServlet() { return new ServletRegistrationBean<>(new MyServlet()); } @Bean public FilterRegistrationBean myFitler() { return new FilterRegistrationBean<>(new MyFilter()); } @Bean public ServletListenerRegistrationBean myListener() { return new ServletListenerRegistrationBean(new MyListener()); } }
Startup You can see the listener boot in the console.
11:35:03.744 INFO 8616 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1364 ms 11:35:03.798 INFO 8616 --- [ main] net.codingme.boot.listener.MyListener : Listener Start Initialization 11:35:03.892 INFO 8616 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 11:35:04.055 INFO 8616 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
Visit the Servlet to see the interceptor and the Servlet in effect.
11:36:55.552 INFO 3760 --- [nio-8080-exec-1] net.codingme.boot.servlet.MyServlet: Servlet initialization started 11:36:55.556 INFO 3760 --- [nio-8080-exec-1] net.codingme.boot.filter.MyFilter: Interceptor begins to intercept 11:36:55.556 INFO 3760 --- [nio-8080-exec-1] net.codingme.boot.servlet.MyServlet: Servlet starts processing GET methods
The article code has been uploaded to GitHub Spring Boot Web Development-Interception Processing.
The article code has been uploaded to GitHub Spring Boot Web Development - Servlet,Filter,Listener.
<Finish>
This article originates from a personal blog: https://www.codingme.net Please indicate the source for reprinting.