为什么要用过滤器或者拦截器?
简单来讲,当一个账户需要进入某个系统调用某个接口时,我们需要对其进行相应验证,否则一旦接口暴露,可能会造成系统崩溃。这个时候我们就需要用拦截器对调用接口一方进行身份验证。
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{
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.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{
// 第一过滤器作日志
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
// TODO Auto-generated method stub
String 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{
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.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 {
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.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:
制作整理不易,以上内容均为原创(参考了部分官方文档和老师整理的案例)。如要引用请附上本文链接,如有疑问可以在评论区畅所欲言,作者看到会第一时间回复,欢迎交流!