对Filter 的认识
1.过滤器,顾名思义在为下一阶段做准备。
2.在web.xml 中位置一个Filter
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd "> <!--配置filter --> <filter> <filter-name>DataFilter</filter-name> <filter-class>cn.filter.DataFilter</filter-class> </filter> <filter-mapping> <filter-name>DataFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>cn.servlet.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/index</url-pattern> </servlet-mapping> </web-app>
在请求 MyServlet 的时候,Filter 会拦截所有的请求
package cn.filter; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DataFilter implements Filter{ public List<String> list ; public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //1.将ServletRequest 转换成 HttpServletRequest final HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse)response; req.setCharacterEncoding("UTF-8"); res.setContentType("text/html;charset=UTF-8"); /** * 问题:编码转换问题,判断表单提交方法是GET还是 POST,GET方式需要特殊处理 * 解决方法:对指定接口的某一个方法进行功能扩展 可以使用动态代理 * 动态代理 request 对象 */ HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance( req.getClass().getClassLoader(), new Class[] { HttpServletRequest.class }, new InvocationHandler() { //这个方法不会被显示调用 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; String methodName = method.getName(); if("getParameter".equals(methodName)){ String username = req.getParameter(args[0].toString()); String submitWay = req.getMethod(); if("GET".equals(submitWay)){ if(username!=null && !"".equals(username.trim())){ username = new String(username.getBytes("ISO8859-1"),"UTF-8"); } } for(String str:list){ if(username.contains(str)){ username = username.replace(str, "***"); } } return username; }else{ obj = method.invoke(req, args); } return obj; } }); chain.doFilter(proxy, res); } public void init(FilterConfig arg0) throws ServletException { list = new ArrayList<String>(); list.add("cnm"); } }
API(参考servlet文档):
FilterChain:doFilter(ServletRequest request, ServletResponse response) 进入到下一个过滤器,若没有就进入到 servlet
FilterConfig:在Filter 中初始化的时候用到,获取名字getFilterName()、得到初始化参数getInitParameter(String name)
Filter 流程
1)tomcat 在启动的时候就会调用Filter 的 init() 方法.
2)注意:在第一次过滤客户端请求的时候进入到 doFilter()方法,在 filterChain.doFilter(req, res); 执行完之后最后又会回到Filter。简言之:Filter-->servlet-->Filter
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException { System.out.println("---> begin doFilter method..1"); filterChain.doFilter(req, res); System.out.println("---> begin doFilter method..2"); }
总结分析:
处理编码过程中,正常情况,需要在每一个servlet里面加上处理编码的代码,这样就必须在每个servlet 里面加上相同的代码,造成代码重复。
这时候我们可以统一集中处理,Filter 就很好的处理了这一问题.