Filter概述

Filter意为滤镜或者过滤器,用于在Servlet之外对request或者response进行修改。Filter提出了过滤链的概念。一个FilterChain包括多个Filter。客户端请求request在抵达Servlet之前会经过FilterChian里的所有Filter,服务器响应response在从Servlet抵达客户端浏览器之前也会经过FileterChain里的所有Filter。Filter处理过程如图所示。

Filter接口

一个Filter必须实现javax.servlet.Filter接口。Filter有三个方法。

public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
} void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; default void destroy() {
}
}

这三个方法反映了Filter的生命周期,其中init与dstory只会被调用一次,分别在web程序加载和卸载的时候调用。而doFilter()方法每次有客户端请求时都会被调用一次。Filter的所有工作集中在doFilter方法中,另外可从init方法传入的filterConfig对象得到filter的初始化参数。

下面是Filter的一个简单实现。

public class TestFilter implements Filter {
public void destroy() {
System.out.println("我被销毁了");
} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("在请求到达Servlet之前我输出了");
chain.doFilter(req, resp);
System.out.println("在响应到达客户端之前我输出了");
} public void init(FilterConfig config) throws ServletException {
System.out.println("我被初始化了");
//得到初始化数据
String value1 = config.getInitParameter("name1");
String value2 = config.getInitParameter("name2");
System.out.println(value1 + " " + value2);
} }

chain.doFilter(req, resp)将request递交给下一个FilterChain的下一个Filter,如果都走完了则交给Servlet处理。

Filter配置

Filter需要在web.xml或@WebFilter注解中配置才能生效。Filter的配置与Servlet的配置非常类似。

在web.xml中需要配置<filter>与<filter-mapping>标签。

<filter>
<filter-name>filtername</filter-name>
<filter-class>filter.TestFilter</filter-class>
<init-param>
<param-name>paraName</param-name>
<param-value>paraValue</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filtername</filter-name>
<url-pattern>*.do</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>

<filter>配置Filter名称,实现类,和初始化参数,可同时配置多个初始化参数,<filter-mapping>配置在什么规则下使用Filter,这两者的filter-name必须匹配。

<url-pattern>配置URL的规则,可以配置多个,可以使用通配符()。例如"/jsp/"适用于本contextPath下以"/jsp"开头的Serlvet,"*.do"适用于所有以".do"结尾的Servlet路径。

<dispatcher>配置到达Servlet的方式。有四种取值:REQUEST,FORWORD,INCLUDE,ERROR。可以同时配置多个<dispatcher>,如果没有配置<dispatcher>,默认为REQUEST。它们的区别为:

  • REQUEST:表示仅当直接请求Servlet时才生效。
  • FORWORD:表示仅当某Servlet通过FORWARD到该Servlet时才生效。
  • INCLUDE:JSP中可以通过jsp:include/请求某Servlet,仅在这种情况下有效。
  • ERROR:JSP中可以通过<%@ page errorPage="error.jsp" %>指定错误处理页面,仅在这种情况下有效。

注意:一个Web程序可以配置多个Filter,这多个Filter的执行顺序有先有后,规则是<filter-mapping>配置在前面的Fliter执行要早与配置在后面的Filter,多个Filter之间可能会相互影响。

在@WebFilter注解中配置,这样就简单多了

@WebFilter(
filterName = "MyFilter",
urlPatterns = "*.do",
initParams = {
@WebInitParam(name="paramName", value = "paramValue")
},
dispatcherTypes = REQUEST
)

应用:字符过滤器

在Servlet里获取请求参数时经常遇到乱码问题,在每个Servlet里处理编码问题就非常麻烦,可以利用过滤器统一处理字符编码问题。你肯定会想到亲自实现那个HttpServletRequest接口,但是如果自己实现的话,要重写里面所有的方法,非常麻烦,所以java提供了HttpServletRequestWrapper类,它已经帮你实现了httpServletRequest接口,你只需要重写你想要重新定义的方法即可。

/**
增强了所有的获取参数的方法
request.getParameterValues("name");
request.getParameter("name");
request.getParameterMap();
*/
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
private boolean flag = true;
public MyRequest(HttpServletRequest request) {
super(request);
this.request=request;
} @Override
public String getParameter(String name) {
if(name==null || name.trim().length()==0){
return null;
}
String[] values = getParameterValues(name);
if(values==null || values.length==0){
return null;
}
return values[0];
} @Override
public String[] getParameterValues(String name) {
if(name==null || name.trim().length()==0){
return null;
}
Map<String, String[]> map = getParameterMap();
if(map==null || map.size()==0){
return null;
}
return map.get(name);
} @Override
public Map<String,String[]> getParameterMap() { /**
* 首先判断请求方式
* 若为post request.setchar...(utf-8)
* 若为get 将map中的值遍历编码就可以了
*/
String method = request.getMethod();
if("post".equalsIgnoreCase(method)){
try {
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}else if("get".equalsIgnoreCase(method)){
Map<String,String[]> map = request.getParameterMap();
if(flag){
for (String key:map.keySet()) {
String[] arr = map.get(key);
//继续遍历数组
for(int i=0;i<arr.length;i++){
//编码
try {
arr[i]=new String(arr[i].getBytes("iso-8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
flag=false;
}
return map;
}
return super.getParameterMap();
} }

接着编写EncodeFilter过滤器,对请求的文本进行编码处理。

/**
* 统一编码
*/
@WebFilter(
filterName = "EncodingFilter",
urlPatterns = "/*"
)
public class EncodingFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
chain.doFilter(new MyRequest(request), response);
} @Override
public void destroy() { } }

Java Web(四) 过滤器Filter的更多相关文章

  1. 【java web】过滤器filter

    一.过滤器简介 过滤器filter依赖于servlet容器 所谓过滤器顾名思义是用来过滤的,Java的过滤器能够为我们提供系统级别的过滤,也就是说,能过滤所有的web请求, 这一点,是拦截器无法做到的 ...

  2. Java Web之过滤器(Filter)

    转: Java Web之过滤器(Filter) 2018年07月31日 16:58:40 喻志强 阅读数 13705更多 所属专栏: Java Web入门   版权声明:本文为博主原创文章, 转载请注 ...

  3. Java Web使用过滤器防止Xss攻击,解决Xss漏洞

    转: Java Web使用过滤器防止Xss攻击,解决Xss漏洞 2018年11月11日 10:41:27 我欲乘风,直上九天 阅读数:2687   版权声明:本文为博主原创文章,转载请注明出处!有时候 ...

  4. JAVA入门[15]-过滤器filter

    一.过滤器 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的: 在客户端的请求访问后端资源之前,拦截这些请求. 在服务器的响应发送回客户端之前,处理这些响应. 参考:http:/ ...

  5. java web(四):request、response一些用法和文件的上传和下载

    上一篇讲了ServletContent.ServletCOnfig.HTTPSession.request.response几个对象的生命周期.作用范围和一些用法.今天通过一个小项目运用这些知识.简单 ...

  6. Java基础95 过滤器 Filter

    1.filter 过滤器的概述 filter过滤器:是面向切面编程的一种实现策略,在不影响原来的程序流程的前提下,将一些业务逻辑切入流程中,在请求达到目标之前进行处理,一般用于编码过滤.权限过滤... ...

  7. 初学Java Web(8)——过滤器和监听器

    什么是过滤器 过滤器就是 Servlet 的高级特性之一,就是一个具有拦截/过滤功能的一个东西,在生活中过滤器可以是香烟滤嘴,滤纸,净水器,空气净化器等,在 Web 中仅仅是一个实现了 Filter ...

  8. Java Web学习总结(29)——Java Web中的Filter和Interceptor比较

    1. 背景 在设计web应用的时候,用户登录/注册是必不可少的功能,对用户登录信息进行验证的方法也是多种多样,大致可以认为如下模式:前端验证+后台验证.根据笔者的经验,一般会在前端进行一些例如是否输入 ...

  9. java web(四)文件上传与下载

     一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...

随机推荐

  1. DjangoBlog安装

    DjangoBlog安装 下载 https://github.com/liangliangyy/DjangoBlog/archive/v7.0.tar.gz pip install -Ur requi ...

  2. Token和SessionStorage(会话存储对象)

    sessionStorage数据只在当前标签页共享 存在本地   关闭浏览器后会清除数据(关闭标签页不会清楚) localStorage数据会存在浏览器中  浏览器关了数据也还在 只有清除缓存才会消失 ...

  3. Linux 中 MySQL常用命令

    一. 数据库登录mysql -uroot -p二..退出数据库quit 和 exit或ctrl + d三.数据库操作1. 查看所有数据库 show databases;2. 查看当前使用的数据库sel ...

  4. dockerfile debian 和pip使用国内源

    python官方镜像是基于debian的.国内使用时定制一下,加快下载速度. 1 debian本身使用国内源 dockfile中: #国内debian源 ADD sources.list /etc/a ...

  5. Spring Cloud 入门教程(一): 服务注册

    1.  什么是Spring Cloud? Spring提供了一系列工具,可以帮助开发人员迅速搭建分布式系统中的公共组件(比如:配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁 ...

  6. rpm命令参数(转载)

    rpm 执行安装包 二进制包(Binary)以及源代码包(Source)两种.二进制包可以直接安装在计算机中,而源代码包将会由RPM自动编译.安装.源代码包经常以src.rpm作为后缀名. 还不清楚具 ...

  7. cocos2dx lua 绑定之一:自动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先定义C++类Student 在cocos2d-x\cocos文件夹下新建一个user_define的文件夹放置两个文件. 注 ...

  8. python Scrapy 常见问题记录

    ImportError: No module named win32api 处理办法 windows系统上出现这个问题的解决需要安装Py32Win模块,但是直接通过官网链接装exe会出现几百个错误,更 ...

  9. angular2 学习笔记 (Typescript - Attribute & reflection & decorator)

    更新 : 2018-11-27 { date: Date } 之前好像搞错了,这个是可以用 design:type 拿到的 { date: Date | null } 任何类型一但配上了 | 就 de ...

  10. Basic Calculator 基本计算器

    2018-09-27 22:02:36 一.Basic Calculator II 问题描述: 问题求解: sign用来保存前一个符号,用num来记录数字,如果碰到一个符号或者到达结尾,则需要进行入栈 ...