Java设计模式:责任链
责任链模式(Chain of Responsibility)的目标是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
在处理用户的请求时可能要根据不同的情况对请求添加不同的处理逻辑,在这时候就可以利用责任链进行设计。当需要添加一个处理逻辑时可以很方便的添加一个处理的节点。
现在我们的需求是处理用户的请求,将用户提交的字符串信息进行层层处理,同时在处理完成之后返回结果时,也要对返回的字符串进行层层处理,而处理返回的情况时其处理的顺序和先前是正好相反的顺序。
首先建立用户的请求和接收对象Request和Response:
- package com.lcq.filter;
- public class Request {
- String requestStr;
- public String getRequestStr() {
- return requestStr;
- }
- public void setRequestStr(String requestStr) {
- this.requestStr = requestStr;
- }
- }
- package com.lcq.filter;
- public class Response {
- String responseStr;
- public String getResponseStr() {
- return responseStr;
- }
- public void setResponseStr(String responseStr) {
- this.responseStr = responseStr;
- }
- }
我们将处理用户信息的逻辑抽象成为一个个的过滤器,进一步抽象出过滤器接口Filter:
- package com.lcq.filter;
- public interface Filter {
- public void doFilter(Request request, Response response,FilterChain chain);
- }
注意在Filte接口中doFilter方法参数中有FilterChain的一个变量,我们再建立FilterChain类:
- package com.lcq.filter;
- import java.util.ArrayList;
- import java.util.List;
- public class FilterChain implements Filter {
- List<Filter> filters = new ArrayList<Filter>();
- int index = 0;
- public FilterChain addFilter(Filter f) {
- this.filters.add(f);
- return this;
- }
- @Override
- public void doFilter(Request request, Response response, FilterChain chain) {
- if (index == filters.size())
- return;
- Filter f = filters.get(index);
- index++;
- f.doFilter(request, response, chain);
- }
- }
在FilterChain中继承了Filter接口,从而实现了doFilter方法,在FilterChain中又有一个index变量,该变量是用来标记当前访问的是哪一个过滤器,这些过滤器是存放在ArrayList中的,这样用户在使用的时候就可以实现自己的过滤器,编写自己的处理逻辑,从而将自己的过滤器添加到ArrayList中,再调用FilterChain的doFilter方法遍历整个责任链。
下面我们编写三个过滤器:
HTMLFilter类:
- package com.lcq.filter;
- /**
- * 过滤HTML中的脚本元素
- * @author lcq
- *
- */
- public class HTMLFilter implements Filter {
- @Override
- public void doFilter(Request request, Response response,FilterChain chain) {
- request.requestStr = request.getRequestStr().replace("<", "[")
- .replace(">", "] --------HTMLFilter");
- chain.doFilter(request, response, chain);
- response.responseStr += "--------HTMLFilter";
- }
- }
SesitiveFilter类:
- package com.lcq.filter;
- public class SesitiveFilter implements Filter {
- @Override
- public void doFilter(Request request, Response response, FilterChain chain) {
- request.requestStr = request.getRequestStr().replace("敏感", " ")
- .replace("猫猫", "haha------SesitiveFilter");
- chain.doFilter(request, response, chain);
- response.responseStr += "------SesitiveFilter";
- }
- }
FaceFilter类:
- package com.lcq.filter;
- public class FaceFilter implements Filter {
- @Override
- public void doFilter(Request request, Response response, FilterChain chain) {
- request.requestStr = request.getRequestStr().replace(":)",
- "^V^-------FaceFilter");
- chain.doFilter(request, response, chain);
- response.responseStr += "-------FaceFilter";
- }
- }
***编写测试类:
- package com.lcq.filter;
- public class Main {
- public static void main(String[] args) {
- String message = "敏感词汇,重庆,<script> 躲猫猫 :)";
- Request request = new Request();
- request.setRequestStr(message);
- Response response = new Response();
- response.setResponseStr("response");
- FilterChain fc = new FilterChain();
- fc.addFilter(new HTMLFilter()).addFilter(new SesitiveFilter());
- FilterChain fc2 = new FilterChain();
- fc2.addFilter(new FaceFilter());
- fc.addFilter(fc2);
- fc.doFilter(request, response,fc);
- System.out.println("request = " + request.getRequestStr());
- System.out.println("response = " + response.getResponseStr());
- }
- }
在上面的实例中应该注意两个地方:
1.我们建立的FilterChain中继承了Filter接口,所以在测试类中就可以像使用其他的过滤器一样使用FilterChain,大大提高了灵活性;
2.对于实现责任链的访问处理顺序问题,该问题的解决使用的是递归的思想,从而使先调用的结点在处理返回结果时其调用过滤器的顺序是相反的。这种解决方案在Struts和其他框架中实现过滤器和拦截器使用的较为普遍,并且十分巧妙。
原文链接:http://blog.csdn.net/liuchangqing123/article/details/7386912
【编辑推荐】
相关文章
- 面试官:JVM是如何判定对象已死的?
- JVM是如何解决跨代引用问题的?
- 垃圾收集器必问系列—CMS
- 垃圾收集器必问系列—ZGC
- Java里面cron表达式工具类,验证corn表达式是不是正确,返回下一个执行时间根据给定的Cron表达式
- Java 里面 @InitBinder注解的使用原理
- Java 实现将long 类型转为带单位的字符串kb,mb,gb等
- 从 Java 的角度看待 Go 的内存管理| 青训营笔记
- Java操作oracle数据库提示:不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK,问题处理
- Java 实现 string类型时间转为 各种各样格式的date类型 的工具类
- 【Java入门】Java数据类型
- java 的 pagehelper.PageHelper实现分页的逻辑
- 【高并发】导致并发编程频繁出问题的“幕后黑手”
- 【高并发】解密导致并发问题的第二个幕后黑手——原子性问题
- 【高并发】一文解密诡异并发问题的第一个幕后黑手——可见性问题
- 开发直播相亲交友源码,高并发怎么做到不卡顿?
- 总之2022,我的研发、直播、软文触达13W+人的成果打包拿走,展望2023一起加油
- 【高并发】要想学好并发编程,关键是要理解这三个核心问题
- Java之赋值运算符
- Java之逻辑运算符