热点新闻
SpringBoot添加过滤器Filter
2023-07-30 10:42  浏览:3102  搜索引擎搜索“手机低淘网”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在手机低淘网看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布

1. 拦截器和过滤器

先说一下,过滤器和拦截器的区别和联系。

1.1 相同点

首先过滤器和拦截器都能实现请求的筛选(过滤或者拦截),然后根据自己的业务需求,添加自己的逻辑,保证请求往后走的时候数据能满足自己的需求。同时呢,他们又都能终止请求流(过滤器只要不在过滤链中往后传request就形;拦截器返回false)。

1.2 不同点

1.2.1 实现原理不同

过滤器和拦截器 底层实现方式大不相同,过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的

1.2.2 使用范围不同

过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Servlet的,生存与Tomcat等服务器容器中,导致它只能在web程序中使用
拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。

1.2.3 触发时机不同

由于过滤器和拦截器基于不同的容器,所以他们的触发时机和请求中经过容器的顺序有关,Filter作用于Servlet,Interceptor作用于Springmvc。





时机,来源于网络

1.2.4 处理范围不同

过滤器处理逻辑都在doFilter方法中,拦截器区分pre、post和after,划分粒度更细了,使用起来更灵活




过滤器





拦截器

1.2.5 拦截器可以注入业务

拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

2. Springboot添加拦截器

项目当中使用过滤器还是拦截器,根据需求来定,一般用哪种都可以,我是要处理requestbody 中的数据(处理特殊字符,加密等)。由于数据还要往下继续传,所以选用filter。
过滤器添加有2种方法:

2.1 通过@WebFilter注解添加

    1. 写过滤器类,并实现Filter接口
    1. 添加@WebFilter注解,属性filterName设置过滤器名称,urlPatterns匹配要过滤的url

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 = "testFilter", urlPatterns = " @Component public class RequestBodyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String contextPath = request.getServletContext().getContextPath(); boolean b1 = HttpMethod.POST.name().equals(req.getMethod()); boolean b2 = ContentType.APPLICATION_JSON.getMimeType().equals(request.getContentType()); boolean b3 = request.getParameterMap().isEmpty(); boolean b4 = contextPath.contains("/test"); if (b1 && b2 && b3 && b4) { MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(req); chain.doFilter(requestWrapper, response); } else { chain.doFilter(request, response); } } }

    1. 将过滤器添加到FilterRegistrationBean,并交给spring容器

import javax.servlet.Filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyFilterConfig { @Autowired private RequestBodyFilter requestBodyFilter; @Bean public FilterRegistrationBean<Filter> someFilterRegistration() { FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>(); registration.setFilter(requestBodyFilter); registration.addUrlPatterns(" public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private byte[] body; public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); final StringBuilder builder = new StringBuilder(); // 缓存按 8192 大小 final CharBuffer buffer = CharBuffer.allocate(2 << 12); BufferedReader reader = null; try { reader = request.getReader(); while (-1 != reader.read(buffer)) { builder.append(buffer.flip()); } } catch (Exception e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } String bodyStr = builder.toString(); try { bodyStr = URLDecoder.decode(bodyStr, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException("body解码出错!"); } body = bodyStr.getBytes(Charset.defaultCharset()); } public byte[] getBody() { return body; } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public boolean isFinished() { return bais.available() == 0; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return bais.read(); } }; } }

总结

  1. 了解过滤器和拦截器的区别
  2. 过滤器推荐使用第2种方法,使用spring管理,可以设置order
  3. 过滤器中如果读取了body数据,需要回写回去,让后续操作能读取到body
发布人:8c0a****    IP:120.244.17.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发