赞
踩
相关问题
相同点
区别
过滤器能实现的功能拦截器基本都能实现,且拦截器不依赖于web容器,尽量用拦截器代替过滤器。
二者触发时机不同,但都可以在controller的方法执行前做一些预处理,以下列出的通用场景基本都是对请求的预处理
1、编写过滤器
import javax.servlet.*; import java.io.IOException; public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //..... //前处理 chain.doFilter(request, response); //...... //后处理 } @Override public void destroy() { } }
2、配置过滤器
一个filter对应一个bean
@Configuration public class FilterConfig { @Bean public FilterRegistrationBean myFilter1() { FilterRegistrationBean filterBean = new FilterRegistrationBean(new MyFilter1()); //要处理的路径 filterBean.addUrlPatterns("/user/**", "/order/**"); //设置执行顺序,浏览器->服务器时,值越小的越先执行;服务器->浏览器则相反 filterBean.setOrder(100); return filterBean; } @Bean public FilterRegistrationBean myFilter2() { FilterRegistrationBean filterBean = new FilterRegistrationBean(new MyFilter2()); filterBean.addUrlPatterns("/**"); return filterBean; } }
以上是配置类方式,也可以使用注解进行配置
//在各个filter类上标注 @WebFilter,需要用@Component体系注解放到容器中
@Component
@WebFilter("/**")
1、编写拦截器
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //无需放到容器中 public class MyInterceptor implements HandlerInterceptor { /** * 在controller中的方法之前执行,返回值标识是否继续后续操作 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //...... return true; } /** * 在controller中方法调用之后、视图解析之前执行,可对Model、View做修改 * 如果要返回的响应是json数据,在执行完controller中的方法后,也会执行此方法 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * 在视图渲染结束之后执行,即在整个请求完成后执行,可用于清理资源、记录日志 * 如果要返回的是json数据,则不会执行此方法 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
2、配置拦截器
@Configuration public class MsInterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { //拦截器1 registry.addInterceptor(new MyInterceptor1()) //要拦截的路径 .addPathPatterns("/**") //排除不拦截的路径 .excludePathPatterns("/xxx") //设置执行顺序,默认0,浏览器->服务器时,值越小的越先执行;服务器->浏览器则相反 .order(100); //拦截器2 registry.addInterceptor(new MyInterceptor2()) .addPathPatterns("/**"); } }
3、多个拦截器的执顺序
HttpServerRequest只能使用一次获取输入流的方法,getInputStream()、getReader()这2个方法都不会重置游标,下次再调用时游标在末尾,读取不到数据,HttpServerResponse同理。
如果要多次读取request中的数据,可以包装一下request,存储输入流,以便后续读取。
wrapper
import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { /** * 存储输入流数据 */ private byte[] body; /** * 构造方法,用于初始化body */ public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); body = new byte[request.getContentLength()]; try { request.getInputStream().read(body); } catch (IOException e) { e.printStackTrace(); } } /** * 重写getInputStream()方法 */ @Override public ServletInputStream getInputStream() throws IOException { ByteArrayInputStream inputStream = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener listener) { throw new UnsupportedOperationException(); } /** * 重写read()方法 */ @Override public int read() throws IOException { return inputStream.read(); } }; } /** * 重写getReader()方法 */ @Override public BufferedReader getReader() throws IOException { InputStreamReader reader = new InputStreamReader(this.getInputStream()); return new BufferedReader(reader); } }
在filter中包装request
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(requestWrapper, response);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。