介绍实现利用过滤器解决的实际问题
请求乱码处理非法请求拦截
介绍过滤器是一种对象,它对资源的请求(servlet或静态内容)或来自资源的响应执行过滤任务,或者两者都执行,在一个web应用中,可以开发编写多个Filter,这些Filter组合起来组合成一个Filter链。若是一个过滤器链,先配置先执行,执行顺序是根据类名的的排序(请求时的执行顺序),响应时以相反的顺序执行,
过滤器在doFilter方法中执行过滤。 每个Filter都可以访问一个FilterConfig对象,它可以从中获取它的初始化参数,以及一个对ServletContext的引用,例如,它可以使用这个引用来加载过滤任务所需的资源。
过滤器在web应用程序的部署描述符中配置。
为该设计确定的例子有:
- 身份验证过滤器日志记录和审计过滤器图像转换过滤器数据压缩过滤器加密的过滤器分过滤器触发资源访问事件的过滤器XSL / T过滤器mime类型过滤器链
需要用到的依赖
org.apache.tomcat tomcat-servlet-api9.0.58 provided javax.servlet javax.servlet-api4.0.1 provided
Filter类
package filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/s01") public class Filter01 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("Filter01的init方法"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("Filter01的doFilter方法"); // 放行资源 filterChain.doFilter(servletRequest, servletResponse); System.out.println("Filter01的响应之后方法"); } @Override public void destroy() { System.out.println("Filter01的destroy方法"); } }
Servlet类
package servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/s01") public class Servlet01 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("Servlet01的service方法"); } }
访问后http://localhost:8080/filter/s01打印
Filter01的doFilter方法 Servlet01的service方法 Filter01的响应之后方法
结论:
- 先执行过滤器的方法再执行servlet的方法响应后会执行过滤器的filterChain.doFilter(servletRequest, servletResponse);后面的代码过滤器也可以设置拦截路径,只对特殊的路径进行拦截
乱码情况
- post请求,所有版本的Tomcat都需要处理,处理方式为servletRequest.setCharacterEncoding("UTF-8");GET请求Tomcat8及以上版本不会乱码,Tomcat7及以下版本会乱码,需要处理
代码案例
package filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.charset.StandardCharsets; @WebFilter("/") public class EncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 基于Http的 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; // 处理get请求且服务器版本在Tomcat8以下 String method = request.getMethod(); if ("GET".equalsIgnoreCase(method)) { // 获取服务器版本 String webVersion = request.getServletContext().getServerInfo(); String version = webVersion.substring(webVersion.indexOf("/") + 1, webVersion.indexOf(".")); if (Integer.parseInt(version) < 8) { // 得到自定义的内部类,(MyWapper继承了) HttpServletRequest myRequest = new Mywapper(request); filterChain.doFilter(myRequest, servletResponse); return; } filterChain.doFilter(servletRequest, servletResponse); } filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } class Mywapper extends HttpServletRequestWrapper { // 定义成员变量,提升构造器中的request对象的范围 private HttpServletRequest request; public Mywapper(HttpServletRequest request) { super(request); this.request = request; } @Override public String getParameter(String name) { String value = request.getParameter(name); if (value != value && !"".equals(value.trim())) { value = new String(value.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); } return value; } } }非法请求拦截
就是有些需要验证通过或者任何情况下都不允许用户访问,直接设置拦截器的拦截路径即可,进入此拦截器就返回
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)