一、摘要:
1)个人常使用过滤器的实现有两种方式,一个是实现Filter,另一个是继承OncePerRequestFilter;
2)个人常使用拦截器的实现方式是,先通过实现HandlerInterceptor,再通过实现WebMvcConfigurer,重写方法addInterceptors(InterceptorRegistry registry)方法,利用入参registry.addInterceptor(new MyInterceptor()),再@Configuration注入到容器使其生效。
二、开发基础,首先这个demo是在springboot web基础框架上建立的,搭建请参照SpringBoot2.X之旅,开篇 hello world(Web Project),在这个基础上引入lombok包(idea需要另外安装lombok插件),pom.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cobra</groupId>
<artifactId>webdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>webdemo</name>
<description>Demo project for Spring Boot</description>
<!--默认是jar包,编译成war包需要重新定义-->
<!--<packaging>war</packaging>-->
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--@Slf4j使用-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
项目包结构:
controller层中HelloWorld 的定义:
package com.cobra.webdemo.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: Baron
* @Description:
* @Date: Created in 2019/3/4 18:40
*/
@RestController
@RequestMapping("/hello")
@Slf4j
public class HelloWorld {
/**
* hello world demo
* @param word
* @return
*/
@RequestMapping(value = "/say",method = RequestMethod.GET)
public String say(@RequestParam("word") String word) {
log.info("say hello "+word+"!!!!!!!!!!!!!!!!!!!!!!!!!!!");
return "hello "+ word+" !";
}
@RequestMapping(value = "/listen",method = RequestMethod.GET)
public String listen() {
log.info("listen........................");
return "i am listening!";
}
}
三、Coding:
A、第一部分,过滤器:
1、自定义MyFilter,继承Filter,实现相应的方法,给类添加注解@WebFilter(urlPatterns = "/hello/*"):
package com.cobra.webdemo.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Author: Baron
* @Description: 过滤器Filter的实现
* @Date: Created in 2019/3/6 18:08
*/
@WebFilter(urlPatterns = "/hello/*")
@Slf4j
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("MyFilter =====>> path"+((HttpServletRequest)servletRequest).getServletPath());
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
2、自定义MyOncePerRequestFilter,继承OncePerRequestFilter,重写doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain)方法,给类添加注解@WebFilter(urlPatterns = "/hello/*"):
package com.cobra.webdemo.filter;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Author: Baron
* @Description:
* @Date: Created in 2019/3/7 18:57
*/
@WebFilter(urlPatterns = "/hello/*")
public class MyOncePerRequestFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
System.out.println("MyOncePerRequestFilter =====>> path="+httpServletRequest.getServletPath());
filterChain.doFilter(httpServletRequest,httpServletResponse);
}
}
3、在启动类上加注解,把过滤器的包进行扫描:
package com.cobra.webdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan(basePackages = "com.cobra.webdemo.filter")
public class WebdemoApplication {
public static void main(String[] args) {
SpringApplication.run(WebdemoApplication.class, args);
}
}
4、启动测试:
5、小结:请求先到Filter,再到OncePerRequestFilter。
B、第二部分,拦截器
1、MyInterceptor实现HandlerInterceptor,实现三个方法,preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)方法需要改成返回值为true。
package com.cobra.webdemo.interceptor;
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;
/**
* @Author: Baron
* @Description: 拦截器的定义
* @Date: Created in 2019/3/7 19:43
*/
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("visit preHandle.......");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("visit postHandle.......");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("visit afterCompletion.......");
}
}
2、定义InterceptorConfig,继承WebMvcConfigurer,重写addInterceptors(InterceptorRegistry registry),添加拦截器,并@Configuration注入:
package com.cobra.webdemo.config;
import com.cobra.webdemo.interceptor.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Author: Baron
* @Description: 拦截器的注入和配置
* @Date: Created in 2019/3/7 19:51
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
/**
* 根据业务需求,也可以Override其他方法
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
//需要拦截的路径,可以是List集合
.addPathPatterns("/hello/*")
//不需要拦截的路径,可以是List集合
.excludePathPatterns("/hello/listen");
}
}
3、启动程序,测试:
4、小结:请求先到Filter,再到OncePerRequestFilter,再到拦截器HandlerInterceptor。