为什么要用过滤器或者拦截器?
简单来讲,当一个账户需要进入某个系统调用某个接口时,我们需要对其进行相应验证,否则一旦接口暴露,可能会造成系统崩溃。这个时候我们就需要用拦截器对调用接口一方进行身份验证。
servlet过滤器的简单使用
第一种:使用servlet注解方式
首先,新建一个springboot工程,引入pom:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional>
</dependency>
其次,新建一个过滤器类:
以下是过滤器详细代码(都是servlet的包):
package com.zhisen.uud.filter;import java.io.IOException;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
//传统过滤器实现。
@WebFilter(filterName = "filter2", urlPatterns = "/*")
public class aTestFilter implements Filter{@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {// TODO Auto-generated method stubSystem.out.println("过滤器a执行了");arg2.doFilter(arg0, arg1);}}
然后再主类中加入注解,扫描过滤器:
最后可以自己在controller建一个接口,用Postman测一下。会发现在接口内容之前过滤器发生了作用。
补充:
当两个拦截器拦截的内容相同时,会根据工程的类名进行字符串比较,然后挨个进行过滤,例如:
当两个过滤器拦截的都为 ‘/*’时,他的执行顺序为,aTestFilter – bTestFilter – 接口
第二种:使用Spring注册Bean的方式
首先,创建一个Filter类实现Filter接口(代码同上,除了注解):
然后再配置类中注册一个bean(里面指定过滤的路径,设置过滤器名称,级别):
之后调用接口,观看结果。
使用注解方式实现三层过滤(日志,参数,权限)
主类:
package com.zhisen.uud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication
//传统的过滤器,去扫描固定包下的
@ServletComponentScan("com.zhisen.uud.filter")
public class UudApplication {public static void main(String[] args) {SpringApplication.run(UudApplication.class, args);}}
接口:
package com.zhisen.uud.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class restTemplateController {
// 无参数传递@GetMapping("/test")public Map<String,Object> test1(){Map<String,Object> result = new HashMap<String, Object>();result.put("A01", "post");try {
// Thread.sleep(2000);} catch (Exception e) {// TODO: handle exception}System.out.println("A01执行了!");return result;}// 无参数传递@GetMapping("/test1")public Map<String,Object> test2(){Map<String,Object> result = new HashMap<String, Object>();result.put("A02", "post");try {
// Thread.sleep(2000);} catch (Exception e) {// TODO: handle exception}System.out.println("A02执行了!");return result;}
}
第一层过滤器:
package com.zhisen.uud.filter;import java.io.IOException;
import java.util.Date;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;@WebFilter(filterName = "filterc", urlPatterns = "/*")
public class cTestFilter implements Filter{// 第一过滤器作日志@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {// TODO Auto-generated method stubString ipString = arg0.getRemoteAddr();Date startDate = new Date();String path = ((HttpServletRequest) arg0).getRequestURI();System.out.println("来自地址:{"+ipString+"} 请求url:{"+path+"} 请求时间:{" +startDate+"}");arg2.doFilter(arg0, arg1);Date fisnishDate = new Date();System.out.println("执行时长:{"+ (fisnishDate.getTime()-startDate.getTime())+"}毫秒");}}
第二层过滤器:
package com.zhisen.uud.filter;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;@WebFilter(filterName = "filterd", urlPatterns = "/*")
public class dTestFilter implements Filter{@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException { // TODO Auto-generated method stubSystem.out.println("参数过滤器执行中");String nameString = arg0.getParameter("userName");//arg0.setAttribute(arg0, arg1); //设置属性,他不是参数if (null == nameString || "".equals(nameString)) {System.out.println("缺少必要参数userName");arg1.setContentType("application/json;charset=utf-8");PrintWriter writer = arg1.getWriter();writer.write("{\"status\":0,\"msg\":\"缺少必要参数userName\"}");
// arg2.doFilter(arg0, arg1);} else {arg2.doFilter(arg0, arg1);}System.out.println("参数过滤器执行完毕");}}
第三层过滤器:
package com.zhisen.uud.filter;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;import org.springframework.web.bind.annotation.RequestMapping;@WebFilter(filterName = "filtere", urlPatterns = "/*")
public class eTestFilter implements Filter {@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {// TODO Auto-generated method stubSystem.out.println("权限过滤器执行中");String path = ((HttpServletRequest) arg0).getRequestURI();if ("/test".equals(path)) {arg2.doFilter(arg0, arg1);} else {String tockenString = arg0.getParameter("token");if (null == tockenString || "".equals(tockenString)) {System.out.println("没有权限");arg1.setContentType("application/json;charset=utf-8");PrintWriter writer = arg1.getWriter();writer.write("{\"status\":0,\"msg\":\"没有权限\"}");} else {arg2.doFilter(arg0, arg1);}}System.out.println("权限过滤器执行完毕");}}
参数齐全结果:
缺少token:
缺少userName:
制作整理不易,以上内容均为原创(参考了部分官方文档和老师整理的案例)。如要引用请附上本文链接,如有疑问可以在评论区畅所欲言,作者看到会第一时间回复,欢迎交流!