JavaWeb之Filter过滤器详解
作者:社会主义接班人 发布时间:2021-06-30 03:40:55
原本计划这一篇来总结JSP,由于JSP的内容比较多,又想着晚上跑跑步减减肥,所以今天先介绍Filter以及它的使用举例,这样的话还有些时间可以锻炼锻炼。言归正传,过滤器从字面理解她的话有拦网、过滤的功能,可以算是JavaWeb的拦精灵。
一、由来
客户端发起请求,那服务器不能什么请求都做出响应,做拦截处理,不仅能减轻服务器的压力,还能保护数据的安全,同样服务端做出响应给客户端时有时也需要进行过滤,比如我们常见的图片添加水印。为了处理这些问题,于是过滤器出现了。有时不仅仅对请求与响应进行一层的过滤,可能会过滤多层,所以提出了滤镜链(FilterChain)的概念.
二、使用
在使用它之前先熟悉下它的作用的地方。过滤器作用在请求Request到达Servlet之前以及响应Response到达浏览器之前会依次经过过虑链。有些类似asp.net中的httpmodule.使用Filter主要是实现javax.servlet.filter接口。查看API可看到有3个方法。
1.public void init(FilterConfig filterConfig) throws ServletException
由 Web 容器调用,指示将放入服务中的过滤器。servlet 容器只在实例化过滤器之后调用一次 init 方法。在要求过滤器做任何过滤工作之前,init 方法必须成功完成。如果 init 方法抛出 ServletException或没有在 Web 容器定义的时间段内返回,则 Web 容器无法将过滤器放入服务中。这个和Servlet的生命周期有点类似,也是只初始化一次,destroy()也是执行一次。
2.public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException
每次由于对链末尾的某个资源的客户端请求而通过链传递请求/响应对时,容器都会调用 Filter 的 doFilter 方法。传入此方法的 FilterChain 允许 Filter 将请求和响应传递到链中的下一个实体。
此方法的典型实现遵循以下模式:
1. 检查请求
2. 有选择地将带有自定义实现的请求对象包装到用于输入过滤的过滤器内容或头中
3. 有选择地将带有自定义实现的响应对象包装到用于输出过滤的过滤器内容或头中
4. a) 既可以使用 FilterChain 对象 (chain.doFilter()) 调用链中的下一个实体,
4. b) 也可以不将请求/响应对传递给过滤器链中的下一个实体,从而阻塞请求处理
5. 在调用过滤器链中的下一个实体之后直接设置响应上的头。
3.public void destroy()
由 Web 容器调用,指示将从服务中取出的过滤器。此方法仅在过滤器的 doFilter 方法中的所有线程都已退出之后调用一次,或者在过了超时期之后调用。在调用此方法之后,Web 容器不会再对此过滤器实例调用 doFilter 方法。此方法为过滤器提供了一个清除持有的所有资源(比如内存、文件句柄和线程)的机会,并确保任何持久状态都与内存中该过滤器的当前状态保持同步。
三、案例
使用过滤器的地方有很多,这里就不一一举例,下面的demo在上篇博客中HelloWorld项目的基础上实现防盗链的功能,以此体会Filter的使用。
1.准备
在HelloWolrd项目中新增一个文件夹,在文件夹中放入两个图片一个err.png 一个test.png,两个图如下
2.创建Filter
这里也没新建Filter包,直接在上一博客中的com.test.cyw包中创建Filter文件MyFilter,应该是创建一个包专门管理Filter类的额,这里只是做测试。创建完成之后可以看到MyFilter继承Filter。
public class MyFilter implements Filter
3.在doFilter中实现防盗链
package com.test.cyw;
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;
import javax.servlet.http.*;
/*@WebFilter("/MyFilter")*/
public class MyFilter implements Filter {
public MyFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest)request;
HttpServletResponse res=(HttpServletResponse)response;
String referer=req.getHeader("referer");//链接来源地址
if(referer==null||!referer.contains(req.getServerName()))
{
req.getRequestDispatcher("/Images/err.png").forward(req, res);
return;
}
chain.doFilter(req, res);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
4.Filter配置
上面只是创建了一个类实现了Filter接口,如何让Tomcat知道呢,这和Servlet类似,需要在Web.xml中配置。和配置servlet有点相同。
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.test.cyw.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/Images/*</url-pattern>
</filter-mapping>
5.测试
新建一个test.jsp文件,在jsp中显示img,可以正常显示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<img alt="防盗链" src="Images/test.png" width="400">
</body>
</html>
如果直接在浏览器输入test.png的地址,则会显示err.png
四、遇到的问题
开始的时候由于地址错误,导致谷歌浏览器test.jsp中显示的也是err.png的图片,但当我换过来时刷新页面还是没变,这个让我很纳闷。有时候将Tomca重启也不行,试了好几次都是这样,实在不行了用IE试了下没想到显示是正确的,原来谷歌浏览器有缓存,导致显示的不正确。
五、总结
Filter用处很多,网上也有好多的例子,做项目时可以先实现一些常用的例如水印,等用的时候只需配置下xml就能解决,很是方便。
来源:http://www.cnblogs.com/5ishare/p/6557079.html
猜你喜欢
- 概述在以下示例中,将介绍在PDF文档页面设置页面切换按钮的方法。示例中将页面切换按钮的添加分为了两种情况,一种是设置按钮跳转到首页、下页、上
- /*** 目的:实现AVL* 利用数组对左右儿子简化代码,但是对脑力难度反而增大不少,只适合acm模板* 其实
- Java实现基于Socket的简单通信 一.ServerSocket1.使用JavaFX写的小界面,方便观察客户端连接情况 &nb
- 关于注入数据说明1.不通过配置文件注入数据通过@Value将外部的值动态注入到Bean中,使用的情况有:注入普通字符串注入操作系统属性注入表
- 当变换Java代码为Ceylon代码时,有时候我会遇到一些Java类构造器混淆了验证与初始化的情形。让我们使用一个简单但是人为的代码例子来说
- 本文想阐述一下当你开发Android应用并采用RxJava作为你的架构,尤其是有关网络请求时最常见的三种场景。我使用Retrofit来作为网
- 大家都知道为了防止我们的网站被有些人和黑客恶意攻击,比如我们网站的注册页面,如果我们在用户注册的时候不加上一个验证码框的话,别人就可以写一个
- 简介我们在开发web应用的时候,有时候为了适应浏览器大小的调整,需要动态对页面的组件进行位置的调整。这时候就会用到flow layout,也
- 一、实现接口调用一个接口中的方法,传统方法:接口类A:package lombda;/** * @author yeqv * @progra
- Android 中RecycleView实现item的点击事件RecycleView现在已经越来越受到大家的重视,因为他既可以代替listV
- idea切换分支时,修改过的代码文件全部不见了找了一下问题,切换分支时,idea自动会创建暂存文件,点开,右边View --> 即可显
- 本文实例为大家分享了安装和配置maven环境的具体步骤,供大家参考,具体内容如下下载maven:1.进入官网下载:http://maven.
- 1.线索化二叉树的介绍将数列 {1, 3, 6, 8, 10, 14 } 构建成一颗二叉树.问题分析:1.当我们对上面的二叉树进行中序遍历时
- 一个图片识别小工具,原先主要是识别以前公司的软件注册码截图里的数字和字母(每次要一个一个框复制出来粘贴到注册器里,很麻烦!),因为注册码出现
- 俄罗斯方块Tetris是一款很经典的益智游戏,之前就做了一款桌面版的java俄罗斯方块,这次就尝试着写了一款适用于Android平台的俄罗斯
- 我就废话不多说了,大家还是直接看代码吧~ public Sprite LoadSourceSprite(string relat
- 公司app要求做一个扭蛋功能,其实就是一个可拖动层叠卡片列表,原理还是由一个自定义Recyclerview和LayoutManager来实现
- 这篇效果和上一篇:https://www.jb51.net/article/100638.htm的效果是一样的,但是不再在OnTouchEv
- 本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下1.RandomAccessFileRandomAcce
- 出处:https://www.cnblogs.com/SunSpringeclipse下面创建的Maven项目,使用mybatis。ecli