JavaWeb Filter

作者: dawsonenjoy | 来源:发表于2018-12-30 22:11 被阅读0次

    过滤器,用于执行过滤任务的对象,针对指定请求响应执行,通过doFilter()方法进行过滤。常用于验证过滤、日志记录、图像转换、数据压缩、加密等方面。

    生命周期

    实例化 -> init() -> doFilter() -> destory(),在doFilter()方法中进行过滤判断,当无需过滤时执行chain.doFilter(request, response)即可

    使用步骤

    1.创建一个类实现Filter接口
    2.重写接口中的方法,其中实现过滤功能的是doFilter()方法
    3.进行路由配置

    注:
    只有执行chain.doFilter(request, response)方法,资源才能够被正常访问到

    Filter路由配置

    配置Filter的作用路由,可以通过两种方式进行配置:在web.xml中进行配置;通过@WebFilter注解进行配置

    1.web.xml配置
    定义

    通过<filter>标签定义一个filter,并为其配置<filter-name><filter-class>

    映射

    通过<filter-mapping>配置映射,主要配置<filter-name><url-pattern>(要过滤的路径),其他还有:
    (1)<servlet-name>代表对指定<servlet-name>的Servlet进行拦截
    (2)<dispatcher>代表当以何种方式去访问web资源时进行拦截,默认是REQUEST(浏览器直接访问时过滤),还有其他参数:FORWARD(转发请求时过滤)、ERROR(通过异常机制调用时过滤)、INCLUDE(通过RequestDispatcher.include()调用时过滤)

    使用举例

    过滤器:

    package com.servlet;
    
    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;
    
    public class FilterTest implements Filter {
    
        public void init(FilterConfig fConfig) throws ServletException {
            // 初始化
        }
    
        public FilterTest() {
        }
    
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            boolean flag = true;
            if (flag) {
                //如果需要过滤,执行的语句
            } else {
                chain.doFilter(request, response);  //执行这句说明内容通过,无需过滤
            }  
        }
    
        public void destroy() {
            // 结束
        }
    }
    

    在web.xml中配置如下:

    <filter>
        <filter-name>test</filter-name>
        <filter-class>com.servlet.FilterTest</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>test</filter-name>
        <url-pattern>/*</url-pattern>  //对所有内容进行过滤
    </filter-mapping>
    
    注解配置

    和Servlet的注解配置类似,举例:

    @WebFilter("/*")
    public class FilterTest implements Filter {
        ...
    }
    
    Filter调用顺序

    当多个Filter对同一个资源进行拦截时,则会形成Filter链,其中调用顺序由<filter-mapping>标签的顺序来确定,举例:

    <filter>
        <filter-name>FilterTest1</filter-name>
        <filter-class>com.mvc.filter.FilterTest1</filter-class>
    </filter>
    <filter>
        <filter-name>FilterTest2</filter-name>
        <filter-class>com.mvc.filter.FilterTest2</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>FilterTest2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>FilterTest1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    结果是FilterTest2先过滤,然后FilterTest1再过滤,虽然是FilterTest1先定义的,但是<filter-mapping>标签里却是FilterTest2在前,所以FilterTest2先进行过滤

    FilterChain

    FilterChain是Servlet提供的对象,里面提供了对某一资源的过滤请求调用链的视图,根据上面的调用顺序可以知道Filter链里由多个Filter组成,而这之间的传递连接就是通过FilterChain来实现的

    FilterConfig

    是Filter的配置对象,在Filter的init()方法中就有传入该参数,主要提供了以下方法:
    1.getFilterName():获取Filter名称
    2.getInitParameter():获取Filter初始化参数
    3.getInitParameterNames():获取所有参数的name
    4.getServletContext():获取ServletContext对象

    编码过滤器

    对于发送过来的数据,可以通过统一设置编码,从而解决乱码问题。

    实现过程

    1.因为get和post方法的解决方式不一样,因此要分开设置。
    2.post方法中直接通过setCharacterEncoding()方法设置即可
    3.get方法中的设置是通过getParameter()获取值以后在通过String(byte[] bytes, String charsetName)来设置的,所以可以通过继承该接口的一个实现类后重写getParameter()方法,使其在获取值的过程当中自动编码,举例:

    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    
    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.HttpServletRequestWrapper;
    
    public class FilterTest implements Filter {
    
        public FilterTest() {
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
        }
    
        public void destroy() {
        }
    
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            if (req.getMethod().equals("POST")) {  //post方法编码设置
                req.setCharacterEncoding("utf-8");
                chain.doFilter(req, response);  //传入编码后的request对象
            } else {  //get方法编码设置
                chain.doFilter(new ChardetSet(req), response);  //传入的request对象里的getParameter方法是重写过的
            }
        }
    }
    
    class ChardetSet extends HttpServletRequestWrapper {  //继承HttpServletRequest接口的一个实现类,这样只用重写需要的方法,而不用像继承接口那样需要把所有方法都实现
        HttpServletRequest request;
    
        public ChardetSet(HttpServletRequest request) {
            super(request);
            this.request = (HttpServletRequest) request;
        }
    
        public String getParameter(String name) {  //重写getParameter方法
            name = request.getParameter(name);
            try {
                return new String(name.getBytes("iso-8859-1"), "utf-8");  //解决get方法乱码
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    这里只重写了getParameter()方法,对于多值的情况还需要去重写getParameterValues()方法,这里仅做个示例

    相关文章

      网友评论

        本文标题:JavaWeb Filter

        本文链接:https://www.haomeiwen.com/subject/yvrslqtx.html