Filter
概念:由Java编写的,线程安全的WEB组件。主要完成对请求的拦截和结果的拦截。
拦截器原理图
拦截器语法
拦截器四个语法点。
接口里没有抽象方法。接口不是类,也不是特殊的类。
请求的预处理, 请求下传chain。
拦截条件根下的所有请求,配置时,不需要loadon-startup。
-
FirstFilter.java
package cn.zte.cx.filter ; import java.io.* ; import javax.servlet.* ; import javax.servlet.http.* ; public class FirstFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { System.out.println("** 过滤器初始化...") ; } //对象类接口的父接口 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request= (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; System.out.println("** 过滤器 doFilter请求拦截 (chain之前)...") ; chain.doFilter(request,response); System.out.println("** 过滤器 doFilter结果拦截 (chain之后)...") ; } public void destroy() { System.out.println("** 过滤器销毁...") ; } } /* <filter> <filter-name>first</filter-name> <filter-class>cn.zte.cx.filter.FirstFilter</filter-class> </filter> <filter-mapping> <filter-name>first</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> */
乱码处理
编码过滤器
-
编码过滤器的启动和请求处理的流程
- 启动Tomcat服务器:
Tomcat服务器开始运行,准备处理客户端(如浏览器)的请求。 - 读取
web.xml
配置文件:
Tomcat加载并解析web.xml
中的配置,了解需要初始化和使用的过滤器(Filter)和Servlet。 - 创建过滤器配置对象:
Tomcat为每个在web.xml
中配置的过滤器创建一个FilterConfig
对象,这个对象包含了过滤器的初始化参数。 - 实例化过滤器:
Tomcat根据web.xml
中的标签创建CharsetEncodingFilter过滤器的实例。 - 初始化过滤器:
调用过滤器的init
方法,并传入FilterConfig
对象。此时,过滤器可以读取它的初始化参数,比如编码方式(如GBK)。 - 浏览器发送请求:
用户通过浏览器发送HTTP请求到Tomcat服务器。 - 过滤器拦截请求:
根据web.xml
中的``配置,Tomcat决定哪些请求需要被哪些过滤器拦截。在本例中,CharsetEncodingFilter
和FirstFilter
都会拦截所有请求(/*
)。 - 处理请求:
- 过滤器首先调用
doFilter
方法,对请求进行预处理。 - 在
doFilter
方法内部,过滤器可以设置请求和响应的编码(如GBK),然后调用chain.doFilter(request, response)
将请求传递给下一个过滤器或目标Servlet。 - 目标Servlet处理请求并生成响应。
- 响应再沿着过滤器链反向传递,每个过滤器可以在响应返回给客户端之前对其进行后处理。
- 过滤器首先调用
- 请求完成:
- 在所有过滤器处理完毕后,最终的响应被发送回浏览器。
- 当Tomcat服务器关闭或过滤器不再需要时,会调用过滤器的
destroy
方法进行清理。
- 启动Tomcat服务器:
-
过滤器的配置
<filter> <!--过滤器的名称:CharsetEncodingFilter,这个名称是唯一的,用于在<filter-mapping>中引用该过滤器--> <filter-name>CharsetEncodingFilter</filter-name> <!--指定了实现该过滤器的Java类:Tomcat在启动时会加载类CharsetEncodingFilter,并创建其实例。--> <filter-class>com.zte.util.CharsetEncodingFilter</filter-class> <!--过滤器的初始化参数:encoding--> <init-param> <param-name>encoding</param-name> <param-value>gbk</param-value> </init-param> </filter> <filter-mapping> <!-- <filter-name> 与<filter>元素中的<filter-name>相匹配,指定了这个映射应用于哪个过滤器。--> <filter-name>CharsetEncodingFilter</filter-name> <!--定义了过滤器应该拦截哪些请求的URL模式,/*代表根下所有请求--> <url-pattern>/*</url-pattern> </filter-mapping>
-
CharsetEncodingFilter.java
package com.zte.util; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** * * @author Administrator * 编码过滤器 */ public class CharsetEncodingFilter implements Filter { private String encoding; public void destroy() { System.out.println("CharsetEncodingFilter.destroy()"); } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; //System.out.println("CharsetEncodingFilter.doFilter()"); //设置字符集 request.setCharacterEncoding(this.encoding); //System.out.println("--------doFilter begin----------"); //如果继续执行其他的操作,必须显示的执行如下语句 chain.doFilter(request, response); //System.out.println("--------doFilter end----------"); } public void init(FilterConfig config) throws ServletException { this.encoding = config.getInitParameter("encoding"); System.out.println("encoding=" + encoding); } }
非法文字拦截器
-
loginTest.htm
<html> <head> <title>用户登录</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <form action = "LoginServlet1" method = "post"> 用户名:<input type = "text" name = "content"> <br></br> <input type = "submit" value="登录"></input> </form> </body> </html>
-
error.jsp
you have illegal characters!
-
CharFilter.java
package cn.zte.cx.filter ; import java.io.* ; import javax.servlet.* ; import javax.servlet.http.* ; public class CharFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { // System.out.println("** 过滤器初始化...") ; } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; String content = request.getParameter("content") ; // 如果indexOf返回-1则表示没有查到所要的内容 if(content!=null) { if(content.indexOf("AAA")==-1) { chain.doFilter(request,response) ; } else { response.sendRedirect("error.jsp") ; // 如果需要的话,此处依然可以使用RequestDispatcher进行跳转 } } else { chain.doFilter(request,response) ; } } public void destroy() { // System.out.println("** 过滤器销毁...") ; } }; /* <filter> <filter-name>char</filter-name> <filter-class>cn.zte.cx.filter.CharFilter</filter-class> </filter> <filter-mapping> <filter-name>char</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> */
请求验证过滤器
-
对请求分析
http://127.0.0.1:8080/WebStudentnew/index.jsp 调用过滤器doFilter方法处理请求 String currentURL=request.getRequestURI(); currentURL=/WebStudentnew/index.jsp currentURL.indexOf("/",1)=14 String targetURL=currentURL.substring(14)= /index.jsp 127.0.0.1:8080/WebStudentnew/login.jsp 调用过滤器doFilter方法处理请求 currentURL=/WebStudentnew/login.jsp targetURL=/login.jsp