java-过滤器

一、过滤器执行流程
    过滤器,设计执行流程:
    1.    用户访问服务器
    2.    过滤器: 对Servlet请求进行拦截
    3.    先进入过滤器, 过滤器处理
    4.    过滤器处理完后, 在放行, 此时,请求到达Servlet/JSP
    5.    Servlet处理
    6.    Servlet处理完后,再回到过滤器, 最后在由tomcat服务器相应用户;

二、自定义类实现过滤器

1、编写DemoFilter类实现Filter接口:

package webCustomFilter;

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 DemoFilter implements Filter {
    public DemoFilter() {
        System.out.println("1、调用构造方法...创建DemoFilter实例对象");
    }

    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("2、初始化过滤器方法...执行init方法...");
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("3、开始执行doFilter方法...");
        chain.doFilter(request, response);
        System.out.println("5、返回执行doFilter方法...");
    }

    public void destroy() {
        System.out.println("6、销毁DemoFilter对象方法...");
    }
}

2、编写DemoServlet的Servlet

package webCustomFilter;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DemoServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("4、servlet中的业务逻辑方法被执行了......");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}


其中web.xml中关于Filter的配置如下:
  <!-- 过滤器配置 -->
    <filter>
        <!-- 过滤器内部名称 -->
        <filter-name>DemoFilter</filter-name>
        <!-- 过滤器类的全名 -->
        <filter-class>webCustomFilter.DemoFilter</filter-class>
    </filter>
    <filter-mapping>
        <!-- filter内部名称 -->
        <filter-name>DemoFilter</filter-name>
        <!-- 需要拦截的servlet资源 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>




三、过滤器相关API
|-- interface  Filter                过滤器核心接口
    Void  init(filterConfig);    初始化方法,在服务器启动时候执行
    Void  doFilter(request,response,filterChain);   过滤器拦截的业务处理方法
    Void destroy();               销毁过滤器实例时候调用

|-- interface  FilterConfig   获取初始化参数信息    
    String    getInitParameter(java.lang.String name)
    Enumeration    getInitParameterNames()

|-- interface  FilterChain     过滤器链参数;一个个过滤器形成一个执行链;
    void doFilter(ServletRequest request, ServletResponse response)  ;  执行下一个过滤器或放行

FilterConfig案例:
比如在web.xml中关于Filter的初始化配置如下
    <filter>
        <!-- 过滤器初始化配置 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>path</param-name>
            <param-value>D://xrk</param-value>
        </init-param>
        <!-- 过滤器内部名称 -->
        <filter-name>DemoFilter</filter-name>
        <!-- 过滤器类的全名 -->
        <filter-class>webCustomFilter.DemoFilter</filter-class>
    </filter>
    <filter-mapping>
        <!-- filter内部名称 -->
        <filter-name>DemoFilter</filter-name>
        <!-- 需要拦截的servlet资源 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
如果需要获取init-param标签中name为encoding和path的值,则在init方法中的代码如下:
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("2、初始化过滤器方法...执行init方法...");
        Enumeration<String> enumeration = filterConfig.getInitParameterNames();
        while(enumeration.hasMoreElements()){
            String name=enumeration.nextElement();
            String initParameter = filterConfig.getInitParameter(name);
            System.out.println(name+"\t"+initParameter);
        }
    }
    
    
四、对指定的请求进行拦截
1、/*表示拦截所有的请求
    <filter-mapping>
        <!-- filter内部名称 -->
        <filter-name>DemoFilter</filter-name>
        <!-- 需要拦截的servlet资源 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
2、拦截指定的jsp
    <filter-mapping>
        <filter-name>DemoFilter</filter-name>
        <url-pattern>/index.jsp</url-pattern>
    </filter-mapping>

3、拦截指定的多个jsp
    <filter-mapping>
        <filter-name>DemoFilter</filter-name>
        <url-pattern>/index.jsp</url-pattern>
        <url-pattern>/list.jsp</url-pattern>
    </filter-mapping>

4、拦截所有的jsp
    <filter-mapping>
        <filter-name>DemoFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

5、默认拦截的类型:
    默认拦截的类型:(直接访问或者重定向)
        <dispatcher>REQUEST</dispatcher>
    拦截转发:
        <dispatcher>FORWARD</dispatcher>
    拦截包含的页面(RequestDispatcher.include(/page.jsp);    对page.jsp也执行拦截)
        <dispatcher>INCLUDE</dispatcher>
    拦截声明式异常信息:
        <dispatcher>ERROR</dispatcher>


五、过滤器案例
几乎每一个Servlet都要涉及编码处理:处理请求数据中文问题!
【GET/POST】
每个servlet都要做这些操作,把公用的代码抽取-过滤器实现!

代码实现思路:
1.    Login.jsp  登陆,输入“中文”
2.    LoginServlet.java   直接处理登陆请求
3.    EncodingFilter.java   过滤器处理请求数据编码:GET/POST

新建一个DemoFilter实现Filter接口,代码如下:
package webCustomFilter;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Enumeration;
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 DemoFilter implements Filter {
    public DemoFilter() {
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest req, ServletResponse rep, FilterChain chain)
            throws IOException, ServletException {
         //System.out.println("3、开始执行doFilter方法...");
        // 1、因为目前的request属于ServletRequest类型,而不是HttpServletRequest类型,需要进行类型转换
        final HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) rep;
        // 处理编码
        // 2、针对post提交方式处理编码模式
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        // 3、针对get方式提交的数据,是因为request.getParameter方法内部没有进行提交方式判断并处理,因此会出现乱码
        //String name = request.getParameter("username");
        //解决办法:使用代理的方式对指定的接口的某一个方法进行功能扩展:即对request对象(目标对象),创建代理对象!
        HttpServletRequest proxy =  (HttpServletRequest)Proxy.newProxyInstance(
                request.getClass().getClassLoader(),
                new Class[]{HttpServletRequest.class},
                new InvocationHandler() {
                    
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result=null;
                        //3.1、获取方法名
                        String methodname=method.getName();
                        //3.2、判断:对getParameter方法进行GET提交中文处理
                        if("getParameter".equals(methodname)){
                            //3.3、获取当前request提交方式
                            String submitMethod=request.getMethod();
                            //3.4、获取当前请求的数值:<input type="text" name="username" />
                            String requestValue=request.getParameter(args[0].toString());
                            //3.5、如果当前提交方式为GET提交
                            if("GET".equals(submitMethod)){
                                if(requestValue!=null && !"".equals(requestValue.trim())){
                                    //转码
                                    requestValue=new String(requestValue.getBytes("ISO8859-1"),"UTF-8");
                                }
                            }
                            return requestValue;
                        }else{
                            result=method.invoke(request, args);
                        }
                        return result;
                    }
                });
        
        //4、放行
        chain.doFilter(proxy, response);
    }

    public void destroy() {
    }
}





猜你喜欢

转载自www.cnblogs.com/littlebear1989/p/8999475.html