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. PHP直接将文件流转换为字符串

    有时候不需要图片直接输出到浏览器,需要如下处理! 输出到浏览器 $qrCode = new QrCode(); $qrCode ->setText('Life is too short to b ...

  2. 力扣(LeetCode) 20. 有效的括号

    给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 注意空字符串可被认 ...

  3. 利用vue-cli3快速搭建vue项目详细过程

    一.介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统.有三个组件: CLI:@vue/cli 全局安装的 npm 包,提供了终端里的vue命令(如:vue create .vue ...

  4. VNPY思维导图架构

    VNPY是使用人数世界第三,国内第一的量化交易框架,封装的接口主要有ctp(期货),wind,xtp(股票)等.内部包含回测.实盘.模拟盘等模块.数据库默认为MongoDB的no-sql数据库,基于p ...

  5. office2016如何激活

    office2016如何激活 一.总结 一句话总结:office2016没有激活成功,下了一个office2013破解版 office2013破解版 二.自己做法 三中的方法点赞蛮多的(100多个), ...

  6. caffe在win10下的安装与配置

    1.Windows环境caffe安装配置(无GPU) 参考:http://www.cnblogs.com/cxyxbk/p/5902034.html 解压caffe-windows文件,将./wind ...

  7. week02 课堂作业

    测试一:(点此看原题目) 运行结果: 测试二:(点此看原题目) 运行结果: 测试三:(点此看原题目) 运行结果:

  8. LeetCode--003--无重复字符的最长子串

    问题描述: 给定一个字符串,找出不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 无重复字符的最长子串是 "abc" ...

  9. webpack基础概念

    中文文档:https://webpack.docschina.org/concepts/ 一个现代 JavaScript 应用程序的静态模块打包器(static module bundler). 在 ...

  10. 流水的新技术,铁打的Linux

    关注嘉为科技,获取运维新知 这一年人工智能火了,凡是带电的专业都往AI上靠,实在靠不上的还可以看AlphaGo下棋,探讨AI能否取代人类.这种全民跟风,比前两年的“云计算”.“大数据”热度还高.就算你 ...