Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain
笔记六中实现了三种过滤器:字符编码过滤、登录权限过滤、敏感词过滤,可是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤。最后response过滤,而且中间几项过滤的顺序不能动态改变。所以这里做个改进。实现一个过滤顺序的FilterChain。
多个Filter的运行顺序在这篇博文中得到非常细致的解说,总结一点。多个过滤器的运行顺序是依据web.xml中不同<filter-mapping>的顺序来先后运行的,比方:
<?xml version="1.0" encoding="UTF-8"? >
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>firstFilter</filter-name>
<filter-class>com.test.filter.FirstFilter</filter-class>
</filter>
<filter>
<filter-name>secondFilter</filter-name>
<filter-class>com.test.filter.SecondFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>secondFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>firstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <servlet>
<servlet-name>firstServlet</servlet-name>
<servlet-class>com.alimama.servlet.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>firstServlet</servlet-name>
<url-pattern>/firstServlet</url-pattern>
</servlet-mapping>
</web-app>
将会先运行secondFilter,再运行firstFilter。
以下是截取的一段实现Filter接口的doFilter代码,用户自己定义的Filter都实现了这个接口:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("before invoke secondFilter's chain.doFilter() ..");
chain.doFilter(request, response);
System.out.println("after invoke secondFilter's chain.doFilter() ..");
}
能够看到第四行的chain.doFilter(request,response);这句代码是Servlet里的Filter技术的核心,它的主要职能是将请求传递给下一个Filter。
不是一下子所有初始化所有的Filter对象。
根据这个思想,我自定义了一个FilterChain来实现多个过滤器的过滤顺序。
//FilterChain.java
package lewa; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class FilterChain {
//private static final String[] filters={"LoginFilter","WordFilter"};
private static final Filter[] filters={new LoginFilter(),new WordFilter()};
private static int count=0;
public void doFilter(ServletRequest request,ServletResponse response,FilterChain fc) throws InstantiationException, IllegalAccessException, Exception{
if(count<filters.length){
//Class<Filter> cls=(Class<Filter>)Class.forName(filters[count]);
//cls.doFilter(request, response);
filters[count++].doFilter(request, response, fc);
}
}
}
静态成员变量filters里的过滤器实例的顺序能够自行定义,以后想更改过滤顺序仅仅要改这个String数组就能够。
对应的其它Filter也做了更改:
//Filter.java
package lewa; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public interface Filter {
public void init();
public void doFilter(ServletRequest reuqest,ServletResponse response,FilterChain fc)throws Exception;
public void destroy();
}
//EncodingFilter.java
package lewa; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class EncodingFilter implements Filter{ @Override
public void init() {
// TODO Auto-generated method stub } @Override
public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)throws InstantiationException, IllegalAccessException, Exception{
// TODO Auto-generated method stub
reuqest.setCharacterEncoding("UTF-8");
fc.doFilter(reuqest, response,fc);
response.setContentType("text/html;charset=UTF-8");
} @Override
public void destroy() {
// TODO Auto-generated method stub
} }
//LoginFilter.java
package lewa; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; public class LoginFilter implements Filter{
public LoginFilter(){} @Override
public void init() {
// TODO Auto-generated method stub } @Override
public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)
throws Exception {
// TODO Auto-generated method stub
HttpServletRequest req=(HttpServletRequest)reuqest;
HttpServletResponse resp=(HttpServletResponse)response;
HttpSession session=req.getSession();
if(session.getAttribute("username")==null){
resp.sendRedirect("login.html");
}else{
fc.doFilter(reuqest, response,fc);//这里必须有一个else,不能直接是运行下一个Filter,由于假设未登陆。
那么敏感词过滤就不必再做,并且能够尝试不加else,你会发现。未登陆前留言会跳转到登陆界面。登陆之后再回到留言界面。
这时候count已经不满足count<filters.length,所以此时敏感词过滤将不会运行。
}
} @Override
public void destroy() {
// TODO Auto-generated method stub } }
//WordFilter.java
package lewa; import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class WordFilter implements Filter{ private static Pattern pattern=null;
public static String str=null; private void loadKeyWordProperties(){
StringBuffer patternBuffer = new StringBuffer();
try{
InputStream in =WordFilter.class.getClassLoader().getResourceAsStream("words.properties");
Properties properties = new Properties();
properties.load(in);
Enumeration<?> enu=properties.propertyNames();
while(enu.hasMoreElements()){
patternBuffer.append((String)enu.nextElement()+"|");
}
patternBuffer.deleteCharAt(patternBuffer.length()-1);
pattern = Pattern.compile(new String(patternBuffer.toString().getBytes("ISO-8859-1"),"UTF-8"));
}catch(IOException e){
e.printStackTrace();
}
}
@Override
public void init() {
// TODO Auto-generated method stub } @Override
public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)
throws InstantiationException, IllegalAccessException, Exception {
// TODO Auto-generated method stub
loadKeyWordProperties();
str=reuqest.getParameter("liuyan");
try{
Matcher m=pattern.matcher(str);
str=m.replaceAll("**");
}catch(Exception e){
e.printStackTrace();
}
fc.doFilter(reuqest, response,fc);
} @Override
public void destroy() {
// TODO Auto-generated method stub }
}
最后Servlet里的代码更改:
package lewa; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class Summary
*/
public class Summary extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Summary() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
Filter filter=new EncodingFilter();
FilterChain fc=new FilterChain();
try {
filter.doFilter(request, response,fc);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PrintWriter out=response.getWriter();
HttpSession session=request.getSession();
String name=(String) session.getAttribute("username");
if(name!=null&&!"".equals(name)) {
name=new String(name.getBytes("ISO-8859-1"),"UTF-8");
}
out.println("<html><head><title>留言板内容</title></head><body>");
out.println("用户名:"+name);
out.println("<br/>"+WordFilter.str+"</body></html>");
}
}
自己定义过滤器链的编写这个是源代码的下载地址。
希望大家多多不吝赐教~~
Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain的更多相关文章
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- Typescript 学习笔记七:泛型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- Go语言学习笔记七: 函数
Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...
- 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整
今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...
- # jsp及servlet学习笔记
目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...
- Servlet学习笔记(四)
目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...
- Servlet学习笔记(三)
目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- python3.4学习笔记(七) 学习网站博客推荐
python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...
随机推荐
- Qt Quick快速入门之线程基础
首先必须明确的是,Qt中的线程使用是相对复杂的,并不像C#中那么随意,特别是结合串口.网络编程等,使用时稍有不慎就会出问题,然后Qt里面经常出了问题就直接崩溃(这个真是谁用谁知道),所以如果在功能上用 ...
- 【贪心】Codeforces Round #480 (Div. 2) C. Posterized
题意:让你对[0,255]这个序列任意划分成一些不重叠的子段,每个子段的大小不超过K.给你n个不超过255的数,让你将每个数替换成它所在子段的任意一个元素,使得最终这个n个数的序列的字典序最小. p[ ...
- 【干货】PHP常见危险函数
passthru() 功能描述:允许执行一个外部程序并回显输出,类似于 exec(). 危险等级:高 exec() 功能描述:允许执行一个外部程序(如 UNIX Shell 或 CMD 命令等). 危 ...
- java 反编译 android 反编译
1. jad http://varaneckas.com/jad/jad158e.linux.intel.zip 下载jad, 给jad运行权限 ,运行 chmod a+x ./jad ./jad ...
- bzoj 4322 东西分配问题
问题:有n个东西,分给m个人,对于每个东西,每个人有喜欢与不喜欢两种态度:like[i][j],如果喜欢,那么他得到该东西时增加的喜悦度为k,否则为1,问是否存在一种分法,使得每个人都达到该人的最低喜 ...
- Python168的学习笔记3
list.extend(),可以拓展list,a=(0,1),b=(2,3) a.extend(b),a就变成(0,1,2,3) 分割字符串(除去字符串中的,\/;之类的),如果用str.split( ...
- yyyy-MM-dd HH:mm:ss is Invalid Date in Safari, IE等浏览器下
一.踩坑背景 在做某个项目的过程中,系统要求兼容safari,在使用Element-ui情况下,用到了datepicker组件,但是datepicker在type为daterange情况下,页面首次加 ...
- 在Hexo中渲染MathJax数学公式
最近学机器学习涉及很多的数学公式,公式如果用截图显示,会比较low而且不方便.因此需要对Hexo做些配置,支持公式渲染.同时文末整理了各种公式的书写心得,比如矩阵.大小括号.手动编号.上下角标和多行对 ...
- Oracle DBA学习篇之SQL_TRACE
SQL_TRACE ; ; set serveroutput on; alter session set sql_trace=true; select count(*) from firefox; a ...
- [JAVA] JAVA 文档注释
Java 程序设计环境 文档注释 javadoc JDK中包含的javadoc工具可以由源文件生成一个HTML文档. javadoc从以下几个特性中抽取信息 包 公有类与接口 公有的和受保护的构造器及 ...