• 注册
当前位置:1313e > 默认分类 >正文

模拟实现Tomcat过滤器链,Struts2拦截器链-设计模式之责任链模式(任务链模式)

模拟实现Tomcat过滤器链,Struts2拦截器链-设计模式之责任链模式(任务链模式)

在javaWeb项目中,大家应该经常会用到这样的代码;

Sevlet  Filter

下方代码作用:用于过滤请求,修改Request对象和Response对象的编码

public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {HttpServletRequest req=(HttpServletRequest) arg0;HttpServletResponse resp=(HttpServletResponse) arg1;req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=UTF-8");arg2.doFilter(req, resp);
}

Struts2 拦截器

下方代码作用:用于实现自定义拦截器功能,实现最为普遍的登陆验证。

 protected String doIntercept(ActionInvocation invocation) throws Exception {//获取session对象(经过struts2包装过)Map session = ActionContext.getContext().getSession();//获取session作用域内是否有值Users user = (Users) session.get("user");if(user!=null){//合法访问return invocation.invoke();}else{//user为空说明未经过登陆,保存错误提示信息,跳到登陆页面ActionContext.getContext().put("noright", "请先登陆再进行操作!");return Action.LOGIN;}}

 

当我们使用多个Filter和 Interceptor时,就会组成一个任务链,什么是任务链呢?  

过滤器链——FilterChain的执行流程

组过滤器对某些web资源进行拦截,那么这组过滤器就称为过滤器链。过滤器的执行顺序和有关(谁在前先执行谁)。

 

那么我们怎么模拟一个这样的功能呢?

 下面我们就用代码简单的模拟一下Sevlet中的FilterChain

项目文件

其中myfilter下的各种filter都实现了Filter接口的doFilter方法,模拟web项目中自定义的Filter对象

下面展示各部分代码:

--------------------------------------------------------------------------------------------关键代码开始----------------------------------------------------------------------------------------

Filter.java

package com.bigfire.chain;/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义接口模拟javax.servlet.Filter接口
public interface Filter {void doFilter(Request req,Response res,FilterChain chain);
}

Tomcat.java

package com.bigfire.chain;import com.bigfire.chain.myfilter.CORSFilter;
import com.bigfire.chain.myfilter.LoginFilter;
import com.bigfire.chain.myfilter.URLEcodeFilter;
import com.bigfire.chain.myfilter.UTF8Filter;/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义类模拟Tomcat容器,产生一些对象。
public class Tomcat {public static void main(String[] args) {Request req = new Request("RequestMsg");//模拟Tomcat产生Request对象Response res = new Response("ResponseMsg");//模拟Tomcat产生Response对象
        FilterChain chain1 = new FilterChain();//创建任务链1FilterChain chain2 = new FilterChain();//创建任务链2
chain2.addFilter(new UTF8Filter())    //在任务链2中添加UTF-8过滤器.addFilter(new URLEcodeFilter())    //在任务链2中添加URLEcode过滤器.addFilter(new URLEcodeFilter());    //在任务链2中添加URLEcode过滤器
        chain1.addFilter(new CORSFilter())    //在任务链1中添加跨域过滤器.addFilter(chain2)                    //在任务链1中添加任务链2.addFilter(new LoginFilter());        //在任务链1中添加登陆过滤器
chain1.doFilter(req, res, chain1);    //执行任务链1
        System.out.println(req.msg);        //输出过滤后的结果System.out.println(res.msg);        //输出过滤后的结果
    }}

Request

package com.bigfire.chain;
/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义类模拟javax.servlet.ServletRequest类
public class Request {public String msg;//模拟Request中的消息public Request() {}public Request(String msg) {this.msg = msg;}
}

Res

package com.bigfire.chain;
/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义类模拟javax.servlet.ServletResponse类
public class Response {public String msg;//模拟Response中的消息public Response() {}public Response(String msg) {this.msg = msg;}
}

FilterChain.java

package com.bigfire.chain;import java.util.ArrayList;
import java.util.List;
/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
/*定义类模拟javax.servlet.FilterChain类过滤器链核心类
*/
public class FilterChain implements Filter{//实现Filter接口
    List list = new ArrayList();//存放过滤器的集合int index = 0;//计数器public int layer = 0;//责任链进入的层数
    @Overridepublic void doFilter(Request req, Response res, FilterChain chain) {if (index == list.size()) return;//如果已经冲到list的结尾了就返回Filter filter = list.get(index);//没有到结尾就拿一个filter;index++;//自增filter.doFilter(req, res, chain);//往里执行
    }//用于添加过滤器,返回值是本对象,方便链式添加public FilterChain addFilter(Filter filter) {if (filter instanceof FilterChain) {//添加的时候判断添加的是否是责任链List temlist=((FilterChain) filter).list;//获取子链中的Filter放到主链容器中for (Filter filter2 : temlist) {this.list.add(filter2);}}else    this.list.add(filter);//普通过滤器添加return this;}
}

--------------------------------------------------------------------------------------------关键代码结束----------------------------------------------------------------------------------------

myfilter包下的过滤器

--------------------------------------------------------------------------------------------自定义过滤器代码开始----------------------------------------------------------------------------------------

CORSFilter.java

package com.bigfire.chain.myfilter;import com.bigfire.chain.Filter;
import com.bigfire.chain.FilterChain;
import com.bigfire.chain.Request;
import com.bigfire.chain.Response;
/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义过滤器用于解决跨域问题
public class CORSFilter implements Filter{@Overridepublic void doFilter(Request req, Response res, FilterChain chain) {System.out.println(chain.layer++);req.msg+="--跨域--";chain.doFilter(req, res, chain);System.out.println(--chain.layer);res.msg+="--跨域--";}
}

LoginFilter.java

package com.bigfire.chain.myfilter;import com.bigfire.chain.Filter;
import com.bigfire.chain.FilterChain;
import com.bigfire.chain.Request;
import com.bigfire.chain.Response;
/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义过滤器用于验证账号密码,过滤一些敏感词。
public class LoginFilter implements Filter{@Overridepublic void doFilter(Request req, Response res, FilterChain chain) {System.out.println(chain.layer++);req.msg+="--登陆--";chain.doFilter(req, res, chain);System.out.println(--chain.layer);res.msg+="--登陆--";}
}

URLEcodeFilter.java

package com.bigfire.chain.myfilter;import com.bigfire.chain.Filter;
import com.bigfire.chain.FilterChain;
import com.bigfire.chain.Request;
import com.bigfire.chain.Response;
/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义过滤器用于URL编码
public class URLEcodeFilter implements Filter{@Overridepublic void doFilter(Request req, Response res, FilterChain chain) {System.out.println(chain.layer++);req.msg+="--URLEcode--";chain.doFilter(req, res, chain);System.out.println(--chain.layer);res.msg+="--URLEcode--";}
}

UTF8Filter.java

package com.bigfire.chain.myfilter;import com.bigfire.chain.Filter;
import com.bigfire.chain.FilterChain;
import com.bigfire.chain.Request;
import com.bigfire.chain.Response;
/*
时间:2019年2月26日    10点47分
内容:设计模式--责任链模式
作者:大火yzs
*/
//定义过滤器用于修改请求的编码方式为UTF-8。
public class UTF8Filter implements Filter{@Overridepublic void doFilter(Request req, Response res, FilterChain chain) {System.out.println(chain.layer++);req.msg+="--UTF8--";chain.doFilter(req, res, chain);System.out.println(--chain.layer);res.msg+="--UTF8--";}
}

 

--------------------------------------------------------------------------------------------自定义过滤器代码结束----------------------------------------------------------------------------------------

 

 运行结果:

0    //任务链第0层
1
2
3
4    //任务链第4层 
4
3
2
1
0
RequestMsg--跨域----UTF8----URLEcode----URLEcode----登陆--
ResponseMsg--登陆----URLEcode----URLEcode----UTF8----跨域--

 

 任务链的这种结构和栈的结构十分相似。

 

转载于:https://www.cnblogs.com/bigfire/p/10442442.html

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 162202241@qq.com 举报,一经查实,本站将立刻删除。

最新评论

欢迎您发表评论:

请登录之后再进行评论

登录