java过滤器流程_新手学java过滤器遇到的问题?

理解过滤器就要很好的理解这个设计模式才行-------责任链设计模式(或者说过滤器设计模式)

参看责任链设计模式(过滤器、拦截器)

责任链设计模式(Chain of Responsibility)的应用有:Java Web中的过滤器链、Struts2中的拦截器栈。

先看一个问题:

给定一个字符串“被就业了:),敏感信息,

本文主要以该问题设计方法的演变来讲解责任链设计模式。

第一种设计:没有任何设计模式

设计了一个MsgProcessor类,完成字符串处理的主要工作。MainClass类是本设计中的测试类。

public class MainClass {

public static void main(String[] args) {

//需要被过滤的语句

String msg = "被就业了:),敏感信息,

//实例化处理类

MsgProcessor mp = new MsgProcessor(msg);

String r = mp.process();

System.out.println(r);

}

}

public class MsgProcessor {

private String msg;

public MsgProcessor(String msg){

this.msg = msg;

}

public String process(){

String r = msg;

//过滤msg中的HTML标记

r = r.replace("<", "<").replace(">", ">");

//过滤敏感词

r = r.replace("敏感", "").replace("被就业", "就业");

return r;

}

}

第二种设计:增加一个Filter接口

在第一种设计中,对字符串的所有处理都放在MsgProcessor类中,扩展性极差。如果要过滤字符串中的笑脸(将”:)”替换成”^_^”),则需要改动MSgProcessor中的process方法。

public interface Filter {

String doFilter(String str);

}

public class HtmlFilter implements Filter {

public String doFilter(String msg) {

String r = msg;

//过滤msg中的HTML标记

r = r.replace("<", "<").replace(">", ">");

return r;

}

}

public class SensitiveFilter implements Filter {

public String doFilter(String msg) {

String r = msg;

//过滤敏感词

r = r.replace("敏感", "").replace("被就业", "就业");

return r;

}

}

public class MsgProcessor {

private String msg;

private Filter[] filters = {new HtmlFilter(),new SensitiveFilter()};

public MsgProcessor(String msg){

this.msg = msg;

}

public String process(){

String r = msg;

for(Filter f : filters){

r = f.doFilter(r);

}

return r;

}

}

此时,如果需要过滤字符串中的笑脸,只需要创建一个类FaceFilter实现Filter接口,并在MsgProcessor类中的filters字段中登记即可。

第三种设计:责任链模式(FilterChain)定义:将一个事件处理流程分派到一组执行对象上去,这一组执行对象形成一个链式结构,事件处理请求在这一组执行对象上进行传递。责任链模式的主要参与角色:

① 事件处理请求对象(Request)

② 执行对象(Handler)

public class FilterChain implements Filter {

public List filters= new ArrayList();

public FilterChain addFilter(Filter f){

filters.add(f);

return this;

}

public String doFilter(String msg) {//执行filters中的doFilter方法即可

String r = msg;

for(Filter f : filters){

r = f.doFilter(r);

}

return r;

}

}

public class MsgProcessor {

private String msg;

private FilterChain chain = new FilterChain();

public MsgProcessor(String msg,Filter Chain){

this.msg = msg;

this.chain = chain;

}

public String process(){

return chain.doFilter(msg);

}

}

public class MainClass {

public static void main(String[] args) {

//需要被过滤的语句

String msg = "被就业了:),敏感信息,

//搞一个过过滤链

FilterChain chain = new FilterChain();

chain.addFilter(new HtmlFilter()).addFilter(new SensitiveFilter());

//实例化处理类

MsgProcessor mp = new MsgProcessor(msg,chain);

String r = mp.process();

System.out.println(r);

}

}

责任链模式加强版

上面的实现的过滤链可以用下图a)表示出来,整个过程只对msg过滤了一次。而JavaWeb中的过滤器链和Struts2中的拦截器栈执行的过程可以形象的表示为图b,☆很重要)。

下面用程序模拟JavaWeb中的过滤器,实现类似于对Request和Response的过滤。主要涉及的类如下所示:

public interface Filter {

void doFilter(Request req,Response resp,FilterChain chain);

}

public class HtmlFilter implements Filter {

public void doFilter(Request req, Response resp, FilterChain chain) {

//过滤req.reqStr中的HTML标记

req.reqStr = req.reqStr.replace("<", "<").replace(">", ">");

req.reqStr += "---HtmlFilter()---";

chain.doFilter(req, resp);

resp.respStr += "---HtmlFilter()---";

}

}

public class SensitiveFilter implements Filter {

public void doFilter(Request req, Response resp, FilterChain chain) {

// 过滤req.reqStr中的敏感词

req.reqStr = req.reqStr.replace("敏感", "").replace("被就业", "就业");

req.reqStr += "===SensitiveFilter";

chain.doFilter(req, resp);

resp.respStr += "===SensitiveFilter";

}

}

public class FilterChain{

private List filters = new ArrayList();

//调用链上的过滤器时,记录过滤器的位置用

private int index = 0;

public FilterChain addFilter(Filter f){

filters.add(f);

return this;

}

public void doFilter(Request req, Response resp) {

if(index == filters.size()) return;

//得到当前过滤器

Filter f = filters.get(index);

index++;

f.doFilter(req, resp, this);

}

}

public class Request {

//在Request中只保持了一个reqStr字段记录对Request的操作

//为了方便模拟,没有将reqStr设置为private

String reqStr;

}

public class Response {

//在Response中只保持了一个respStr字段记录对Response的操作

//为了方便模拟,没有将respStr设置为private

String respStr;

}

package org.flyne.fiter;

public class MainClass {

public static void main(String[] args) {

// 需要被过滤的语句

String msg = "被就业了:),敏感信息,

//创建Request、Response对象

Request req = new Request();

Response resp = new Response();

req.reqStr = msg;

resp.respStr = "response";

//搞一个过滤链,链上有两个过滤器

FilterChain chain = new FilterChain();

chain.addFilter(new HtmlFilter())

.addFilter(new SensitiveFilter());

//开始过滤

chain.doFilter(req, resp);

System.out.println(req.reqStr);

System.out.println(resp.respStr);

}

}

转载请注明: 东风化宇 2014年09月07日 于 Flyne 发表---------------------------------------------------------------------------------------------------------

下面我们看看Servlet中实现过滤器的操作,何其相似,如出一辙

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.http.HttpServlet;

public class EncodeFilter extends HttpServlet implements Filter

{

private FilterConfig filterConfig;

String encoding;

public void init(FilterConfig filterConfig) throws ServletException

{

encoding = filterConfig.getInitParameter("encoding");

this.filterConfig = filterConfig;

}

// Process the request/response pair

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

{

try

{

request.setCharacterEncoding(encoding);

response.setContentType("text/html;charset=UTF-8");

filterChain.doFilter(request, response);

} catch (ServletException sx)

{

filterConfig.getServletContext().log(sx.getMessage());

} catch (IOException iox)

{

filterConfig.getServletContext().log(iox.getMessage());

}

}

// Clean up resources

public void destroy()

{

}

}

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.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class LoginFilter extends HttpServlet implements Filter

{

private static final long serialVersionUID = 1L;

private FilterConfig filterConfig;

// Handle the passed-in FilterConfig

public void init(FilterConfig filterConfig) throws ServletException

{

this.filterConfig = filterConfig;

}

// Process the request/response pair

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)

{

try

{

HttpServletRequest request = (HttpServletRequest) req;

HttpServletResponse response = (HttpServletResponse) resp;

HttpSession sess = request.getSession();

String page = request.getServletPath();

if (!"/index.jsp".equals(page) && !"/image.jsp".equals(page))

{

// 当前访问的不是登录页面

// 有没有登录过

if (sess.getAttribute("userName") == null)

{

// 没有登录

response.sendRedirect("index.jsp");

}

}

filterChain.doFilter(req, resp);

} catch (ServletException sx)

{

filterConfig.getServletContext().log(sx.getMessage());

} catch (IOException iox)

{

filterConfig.getServletContext().log(iox.getMessage());

}

}

// Clean up resources

public void destroy()

{

}

}

import java.io.IOException;

import java.io.PrintWriter;

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.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class RightFilter extends HttpServlet implements Filter

{

private static final long serialVersionUID = 1L;

private FilterConfig filterConfig;

// Handle the passed-in FilterConfig

public void init(FilterConfig filterConfig) throws ServletException

{

this.filterConfig = filterConfig;

}

// Process the request/response pair

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)

{

try

{

HttpServletRequest request = (HttpServletRequest) req;

HttpServletResponse response = (HttpServletResponse) resp;

PrintWriter out = response.getWriter();

HttpSession sess = request.getSession();

// 从Session取出用户可以访问的地址

String[] rightUrl = (String[]) sess.getAttribute("rightUrl");

System.out.println("执行用户权限过滤");

String page = request.getServletPath();

System.out.println("你当前访问的路径为:" + page);

if ("/login.do".equals(page) || ("/myRight.do").equals(page))

{

filterChain.doFilter(request, response);

return;

}

boolean isCall = false;

for (int i = 0; i < rightUrl.length; i++)

{

if (page.equals(rightUrl[i]))

{

isCall = true;

break;

} else

{

isCall = false;

}

}

if (isCall == true)

{

System.out.println("允许访问");

filterChain.doFilter(request, response);

} else

{

System.out.println("无权访问");

out.print("对不起,您无权访问");

}

} catch (ServletException sx)

{

filterConfig.getServletContext().log(sx.getMessage());

} catch (IOException iox)

{

filterConfig.getServletContext().log(iox.getMessage());

}

}

// Clean up resources

public void destroy()

{

}

}上面三个过滤器就是使用了责任链设计模式的加强版本

下面看在web.xml当中的配置

encodefilter

com.sanqing.filter.EncodeFilter

encoding

UTF-8

encodefilter

/*

loginFilter

com.sanqing.filter.LoginFilter

loginFilter

*.jsp

rightfilter

com.sanqing.filter.RightFilter

rightfilter

*.do

不难想像Tomcat容器对这些配置和实现类做了什么事情,读取配置文件,将这些实现类全部加入到FilterChain中的List集合中去,当请求来的时候,首先调用FilterChain的doFilter()方法

------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值