Java web

JavaWeb Filter

2018-12-30  本文已影响0人  dawsonenjoy

过滤器,用于执行过滤任务的对象,针对指定请求响应执行,通过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()方法,这里仅做个示例

上一篇 下一篇

猜你喜欢

热点阅读