Java Web(四) 过滤器Filter
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的更多相关文章
- 【java web】过滤器filter
一.过滤器简介 过滤器filter依赖于servlet容器 所谓过滤器顾名思义是用来过滤的,Java的过滤器能够为我们提供系统级别的过滤,也就是说,能过滤所有的web请求, 这一点,是拦截器无法做到的 ...
- Java Web之过滤器(Filter)
转: Java Web之过滤器(Filter) 2018年07月31日 16:58:40 喻志强 阅读数 13705更多 所属专栏: Java Web入门 版权声明:本文为博主原创文章, 转载请注 ...
- Java Web使用过滤器防止Xss攻击,解决Xss漏洞
转: Java Web使用过滤器防止Xss攻击,解决Xss漏洞 2018年11月11日 10:41:27 我欲乘风,直上九天 阅读数:2687 版权声明:本文为博主原创文章,转载请注明出处!有时候 ...
- JAVA入门[15]-过滤器filter
一.过滤器 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的: 在客户端的请求访问后端资源之前,拦截这些请求. 在服务器的响应发送回客户端之前,处理这些响应. 参考:http:/ ...
- java web(四):request、response一些用法和文件的上传和下载
上一篇讲了ServletContent.ServletCOnfig.HTTPSession.request.response几个对象的生命周期.作用范围和一些用法.今天通过一个小项目运用这些知识.简单 ...
- Java基础95 过滤器 Filter
1.filter 过滤器的概述 filter过滤器:是面向切面编程的一种实现策略,在不影响原来的程序流程的前提下,将一些业务逻辑切入流程中,在请求达到目标之前进行处理,一般用于编码过滤.权限过滤... ...
- 初学Java Web(8)——过滤器和监听器
什么是过滤器 过滤器就是 Servlet 的高级特性之一,就是一个具有拦截/过滤功能的一个东西,在生活中过滤器可以是香烟滤嘴,滤纸,净水器,空气净化器等,在 Web 中仅仅是一个实现了 Filter ...
- Java Web学习总结(29)——Java Web中的Filter和Interceptor比较
1. 背景 在设计web应用的时候,用户登录/注册是必不可少的功能,对用户登录信息进行验证的方法也是多种多样,大致可以认为如下模式:前端验证+后台验证.根据笔者的经验,一般会在前端进行一些例如是否输入 ...
- java web(四)文件上传与下载
一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...
随机推荐
- ROC与AUC原理
来自:https://blog.csdn.net/shenxiaoming77/article/details/72627882 来自:https://blog.csdn.net/u010705209 ...
- 力扣(LeetCode)1016. 子串能表示从 1 到 N 数字的二进制串
给定一个二进制字符串 S(一个仅由若干 '0' 和 '1' 构成的字符串)和一个正整数 N,如果对于从 1 到 N 的每个整数 X,其二进制表示都是 S 的子串,就返回 true,否则返回 false ...
- Mint wine
卸载 http://blog.csdn.net/ouyangying123/article/details/459126051.终端中执行sudo apt-get remove wine1.3(win ...
- Lua和C++交互 学习记录之七:C++全局函数注册为Lua模块
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
- (转)C# Stopwatch详解
C# Stopwatch类 命名空间:System.Diagnostics; namespace System.Diagnostics { // 提供一组方法和属性,可用于准确地测量运行时间. pub ...
- Very Good Article on How Git Commands Work
http://stackoverflow.com/questions/30038999/differences-between-commit-commit-and-push-commit-and-sy ...
- 7.2内存管理-ARC
@0-简介 1编译器会自动在适当的地方插入适当的retain.release.autorelease语句 @1-ARC的判断原则 1只要还有一个强指针变量指向对象,对象就会保持在内存中 2强指针 ...
- linux下编译C/C++ 程序
C/C++的速度是Python和perl所无法比拟的,尤其对于处理超大的生物信息学文件来说. 最近在写一个最简单的fastq cut工具,Python简直慢到不能忍,8G的fastq.gz文件的cut ...
- 20180831xlVBA_WorksheetsCosolidate
Sub WorkSheetsConsolidate() Rem 设置求和区域为 单元格区域;单元格区域 Const Setting As String = "A1;B2:C4" D ...
- caffe---mnist数据集训练与测试
1.数据.mnist_test_lmdb和mnist_train_lmdb数据 2.路径. (1)修改lenet_train_test.prototxt文件,训练和测试两处 source: " ...