天天看点

java 过滤器_Java过滤器(Filter)

一、用途

对web的请求或响应进行拦截并做一些业务逻辑判断和处理。

例如:可以使用过滤器拦截一个request来做一些预处理,然后再交给下一个过滤器或servlet进一步处理(也可以对返回的response进行拦截过滤)。

应用场景:

1.身份验证

2.记录和审核

3.图像转换

4.数据压缩

5.加密

6....

二、工作原理

java 过滤器_Java过滤器(Filter)

流程图

过滤器是随着web应用的启动而启动的,只会初始化一次,之后便可以拦截过滤相关的请求或响应,当web应用停止或重新部署的时候才会被销毁。

下面我们通过代码示例来学习如何使用它。

三、上代码

Filter接口源码:

package javax.servlet;

import java.io.IOException;

public interface Filter {

public default void init(FilterConfig filterConfig) throws ServletException {}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException;

public default void destroy() {}

}

可以看到,在Filter接口中定义了一个doFilter方法,该方法正是过滤器执行过滤动作的方法;

每个过滤器都有权访问filterConfig对象,并从中获取初始化参数;

当我们编写好Filter的实现类,并在web应用程序的部署描述符「web.xml」中配置好需要拦截过滤的web资源后,web服务器就会在调用web资源的service方法之前先调用这个doFilter方法 。

此时你就可以针对需要拦截过滤的web资源(Request、Response)进行业务逻辑判断和处理,从而简化操作。

例如:统一设置字符编码、判断用户是否已经登陆、判断有没有权限访问页面等...

Filter的开发主要分为2步:

1.编写java类,实现Filter接口及其方法

package com.ys.test;

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import java.io.IOException;

import java.util.Enumeration;

@WebFilter(filterName = "TestFilter")

public class TestFilter implements Filter {

public void init(FilterConfig config) throws ServletException {

System.out.println("TestFilter初始化...");

Enumeration paramNames = config.getInitParameterNames();

while (paramNames.hasMoreElements()) {

String paramName = paramNames.nextElement();

String paramValue = config.getInitParameter(paramName);

System.out.println(paramName + "=" + paramValue);

}

}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

chain.doFilter(req, resp);

System.out.println("TestFilter被执行...");

// 针对req和resp统一设置字符编码

req.setCharacterEncoding("UTF-8");

resp.setCharacterEncoding("UTF-8");

resp.setContentType("text/html;charset=UTF-8");

// 放行,顺着过滤链继续往下走,若下一个目标仍是Filter,则执行该Filter的doFilter方法

// 若下一个目标是Servlet,则调用Servlet的service方法

chain.doFilter(req, resp);

}

public void destroy() {

System.out.println("TestFilter被销毁!");

}

}

2.配置需要拦截过滤的web资源

在web.xml 文件中使用和元素对编写的Filter实现类进行注册,并设置它所能拦截的web资源

统一字符编码过滤器

characterEncodingFilter

com.ys.test.TestFilter

初始化参数1

encoding1

GBK

初始化参数2

encoding2

UTF-8

characterEncodingFilter

*.do

REQUEST

FORWARD

INCLUDE

ERROR

ASYNC

也可以直接在Filter的实现类中使用@WebFilter注解来注册

@WebFilter(filterName = "TestFilter",

// 配置初始化参数

initParams = {@WebInitParam(name = "encoding1", value = "GBK"), @WebInitParam(name = "encoding2", value = "UTF-8")},

// 配置要拦截的资源

urlPatterns = "*.do",

// 配置拦截的类型

dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR, DispatcherType.ASYNC})

public class TestFilter implements Filter {

...

四、拦截方式配置

拦截方式配置也就是指定过滤器的调度模式,主要有下面几种:

REQUEST

默认值,浏览器直接请求资源。

FORWARD

转发访问资源:RequestDispatcher.forward();

如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用。

INCLUDE

包含访问资源:RequestDispatcher.include();

如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。

ERROR

错误跳转资源:被声明式异常处理机制调用的时候;

如果目标资源是通过声明式异常处理机制调用时,那么过滤器被将被调用。

ASYNC(Servlet3.0新增加)

支持异步处理