1.servlet过滤器
用于动态的拦截servlet请求或响应,以变更或使用其中的信息。
(1)过滤器和servlet是多对多的关系,即一个过滤器可以用于一个或多个servlet,多个过滤器也可以用于一个或多个servlet
(2)过滤器是一个继承与Javax.servlet.Filter接口的类,Filter接口中有三个方法抽象方法:
当web程序启动时,web服务器将调用init(方法),创建一个过滤器的实例,可以在过滤器类中重写init方法,然后通过init方法参数FilterConfig得到过滤器的配置信息,
,
doFilter是直接处理过滤请求的方法,我们可以在这个方法里面编写具体的过滤操作,然后通过 chain.doFilter(request,response);将请求传回过滤链,继续执行以后的操作,直到所有过滤器执行完毕,再执行对应的servlet
在调用servlet的service()方法之前,容器会先创建一个filterchain(过滤链),并把servlet传入这个filterchain对象,作为其内部参数。创建这个filter chain的时候,会根据请求的uri,把符合条件的filter加入到这个chain里。紧接着就调用这个filter chain的doFilter方法。这个filter chain的doFilter方法就会按顺序(在web.xml(servlet-mapping)定义的顺序)调用各个filter的doFilter方法。当所有的filter的doFilter方法都调用完以后,才会调用servlet的service方法。
destroy方法用于关闭服务器时,销毁过滤器的实例
(3)一个servlet对应的所有过滤器的执行顺序:取决于filter-mapping在web.xml中的顺序
<filter>
指定一个过滤器。
<filter-name>
用于为过滤器指定一个名字,该元素的内容不能为空。
<filter-class>元素用于指定过滤器的完整的限定类名。
<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。 在过滤器中,可以使用FilterConfig
接口对象来访问初始化参数。
<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>
元素中声明过的过滤器的名字
<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
<servlet-name>指定过滤器所拦截的Servlet名称。
<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST
,INCLUDE
,FORWARD
和ERROR
之一,默认REQUEST。
用户可以设置多个<dispatcher>
子元素用来指定 Filter 对资源的多种调用方式进行拦截。 <dispatcher>子元素可以设置的值及其意义
REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWAR:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
代码:
public class LogFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // servlet处理之前对参数进行处理 servletRequest.setCharacterEncoding("utf-8"); // 把请求传回过滤链 filterChain.doFilter(servletRequest,servletResponse); //servlet处理完之后对处理数据进行改变 servletResponse.setContentType("text/html;charset=utf-8"); servletResponse.getWriter().print("改变"); } @Override public void destroy() { } }
<filter> <filter-name>logFilter</filter-name> <filter-class>com.app.filter.LogFilter</filter-class> </filter> <filter-mapping> <filter-name>logFilter</filter-name> <!--<servlet-name>HelloWorld</servlet-name>--> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <servlet> <servlet-name>HelloWorld</servlet-name> <servlet-class>com.app.servlet.HelloWorld</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>HelloWorld</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>