过滤器 过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应。 如下图,浏览器发出的请求先递交给第一个filter进行过滤,符合规则则放行,递交给filter链中的下一个过滤器进行过滤。过滤器在链中的顺序与它在web.xml中配置的顺序有关,配置在前的则位于链的前端。当请求通过了链中所有外汇返佣http://www.fx61.com/过滤器后就可以访问资源文件了,如果不能通过,则可能在中间某个过滤器中被处理掉。 过滤器一般用于登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换等等操作,便于代码的重用,不必每个servlet中还要进行相应的操作。 过滤器的简单应用: 1、新建一个class,实现接口Filter(注意:是javax.servlet中的Filter)。 2、重写过滤器的doFilter(request,response,chain)方法。另外两个init()、destroy()方法一般不需要重写。在doFilter方法中进行过滤操作。 3、在web.xml中配置过滤器。这里要谨记一条原则:在web.xml中,监听器>过滤器>servlet。也就是说web.xml中监听器配置在过滤器之前,过滤器配置在servlet之前,否则会出错。 <filter> <filter-name>loginFilter</filter-name>//过滤器名称 <filter-class>com.nnngu.filter.loginFilter</filter-class>//过滤器类的包路径 <init—param> //可选 <param—name>参数名</param-name>//过滤器初始化参数 <param-value>参数值</param-value> </init—pamm> </filter> <filter-mapping>//过滤器映射 <filter-name>loginFilter</filter-name> <url—pattern>指定过滤器作用的范围</url-pattern> </filter-mapping> <url-pattren>处定义过滤器作用的范围。一般有以下规则: 1、作用与所有web资源:<url—pattern>/*</url-pattern>。则客户端请求访问任意资源文件时都要经过过滤器的过滤,通过则可以访问,否则不能访问。 2、作用于某一文件夹下所有文件:<url—pattern>/dir/*</url-pattern> 3、作用于某一种类型的文件:<url—pattern>*.扩展名</url-pattern>。比如<url—pattern>*.jsp</url-pattern>过滤所有对jsp文件的访问请求。 4、作用于某一文件夹下某一类型文件:<url—pattern>/dir/*.扩展名</url-pattern> 如果一个过滤器需要过滤多种文件,则可以配置多个<filter-mapping>,一个mapping定义一个url-pattern来定义过滤规则。如下: <filter> <filter-name>loginFilter</filter-name> <filter-class>com.nnngu.filter.loginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> 例1:用过滤器实现登录验证,没登录则驳回访问请求并重定向到登录页面。 public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) arg0; HttpServletResponse response=(HttpServletResponse) arg1; HttpSession session=request.getSession(); String path=request.getRequestURI(); Integer uid=(Integer)session.getAttribute("userid"); if(path.indexOf("/login.jsp")>-1){//登录页面不过滤 arg2.doFilter(arg0, arg1);//递交给下一个过滤器 return; } if(path.indexOf("/register.jsp")>-1){//注册页面不过滤 arg2.doFilter(request, response); return; } if(uid!=null){//已经登录 arg2.doFilter(request, response);//放行,递交给下一个过滤器 }else{ response.sendRedirect("login.jsp"); } } 例2:设置字符编码 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request2=(HttpServletRequest) request; HttpServletResponse response2=(HttpServletResponse) response; request2.setCharacterEncoding("UTF-8"); response2.setCharacterEncoding("UTF-8"); chain.doFilter(request, response); } 创建Filter 创建一个类然后实现Filter 注意: 导入的包是javax.servlet.Filter下的包 初始化init是再启动tomcat的时候进行初始化的 doFilter中的chain.doFilter是放行的方法 建议把doFilter中的request和response转换为带协议的HttpServletRequset和HttpServletResponse 因为带协议的Http是不带协议的子类,里面的方法比父类更丰富,方便后面调用方法 下面是创建Filter的实例代码 package cn._02FilterChain; import java.io.IOException; 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.annotation.WebFilter; @WebFilter("/chain") public class AFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest) request; HttpServletResponse resp=(HttpServletResponse) response; System.out.println("A放行之前+++"); chain.doFilter(req, resp); System.out.println("A放行之后---"); } @Override public void destroy() { // TODO Auto-generated method stub } } Filter再web.xml中的配置 配置方式有 1.再web.xml中进行配置 2.再类中加上@WebFilter("拦截路径"); filter链式的执行方式 调用方式是按照配置的<filter-mapping>来调用的 下面是web.xml的实例代码 <filter> <filter-name>chainA</filter-name> <filter-class>cn._02FilterChain.AFilter</filter-class> </filter> <filter> <filter-name>chainB</filter-name> <filter-class>cn._02FilterChain.BFilter</filter-class> </filter> <filter> <filter-name>chainC</filter-name> <filter-class>cn._02FilterChain.CFilter</filter-class> </filter> <!-- 执行顺序按照filter-mapping执行 --> <filter-mapping> <filter-name>chainB</filter-name> <url-pattern>/chain</url-pattern> </filter-mapping> <filter-mapping> <filter-name>chainA</filter-name> <url-pattern>/chain</url-pattern> </filter-mapping> <filter-mapping> <filter-name>chainC</filter-name> <url-pattern>/chain</url-pattern> </filter-mapping> package com.zzxtit.common.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class CharacterEncodingFilter implements Filter{ private static String encoding = "UTF-8"; public void init(FilterConfig filterConfig) throws ServletException { encoding = filterConfig.getInitParameter("encoding") == null ? "UTF-8" : filterConfig.getInitParameter("encoding"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(encoding); } } 注 : (1)使用getInitPamater是从web.xml里获取变量enciding的默认值 (2)chain的作用 :一般filter都是一个链,web.xml里配置了几个就有几个。一个一个连在一起,chain.doFilter()将请求转发给过滤器链下一个filter 代码实现 <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.zzxtit.common.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
|