设计模式(一)Chain Of Responsibility责任链模式
设计模式篇章,源于网课的学习,以及个人的整理
在我们接收用户提交的字符时,常常会使用到过滤,在学习责任链模式前,我们是这样做的
1.定义一个类
public class MsgProcesser { String msg; public MsgProcesser(String msg) { this.msg=msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String process() { String r=msg.replace("<", "[").replaceAll(">", "]"); r=r.replaceAll("被就业", "就业"); r=r.replaceAll("敏感", ""); return r; } }
测试
public static void main(String[] args) { String message="大家好:),<script>,敏感,被就业,网络授课没感觉,因为看不见大家伙儿"; MsgProcesser mp=new MsgProcesser(message); System.out.println(mp.process()); }
往往添加数据会很不方便,于是,借用责任链的方式,我们可以这样写
1.定义一个接口,内部有抽象方法doFilter
package com.littlepage.testChainOfResponsibility; public interface Filter { String doFilter(String str); }
2.定义一些不同的过滤器类实现过滤器接口,类似HTMLFilter,SensitiveFilter
package com.littlepage.testChainOfResponsibility; public class HTMLFilter implements Filter{ @Override public String doFilter(String str) { return str.replaceAll("<", "[").replaceAll(">", "]"); } }
package com.littlepage.testChainOfResponsibility; public class SensitiveFilter implements Filter{ @Override public String doFilter(String str) { return str.replaceAll("敏感", "*"); } }
3.进行主要链条的编写,就是新建一个类叫MsgProcesser,该类将这些方法进行串起来,使用foreach循环进行迭代进行过滤,在后续情况下,也就是说,你需要再添加过滤的关键字,就可以直接新建一个链条上的小块(也就是一个类),进行添加,而不用再去写其他东西
package com.littlepage.testChainOfResponsibility; public class MsgProcesser { Filter[] filter= {new HTMLFilter(),new SensitiveFilter()}; String msg; public MsgProcesser(String msg) { this.msg=msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String process() { String r=msg; for(Filter f:filter) { r=f.doFilter(r); } return r; } }
图示:
或者说,你依然可以定义一个责任链类(FilterChain)用来代替MsgProcesser类,里面用ArrayList容器盛放filter
该代码为:
package com.littlepage.testChainOfResponsibility; import java.util.ArrayList; import java.util.List; public class FilterChain { List<Filter> filters=new ArrayList<>(); public FilterChain addFilter(Filter f) { filters.add(f); return this; } public String doFilter(String str) { String r=str; for (Filter filter : filters) { r=filter.doFilter(r); } return r; } }
主方法的调用改为
package com.littlepage.testChainOfResponsibility; public class Main { public static void main(String[] args) { String message="大家好:),<script>,敏感,被就业,网络授课没感觉,因为看不见大家伙儿"; FilterChain fc=new FilterChain(); fc.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter()); System.out.println(fc.doFilter(message)); } }
若该FilterChain也实现Filter接口,那么就可以自己添加自己的FilterChain了,很巧妙
由此可以拓展出,tomcat下可以加上request和response过滤器
代码如下:
package top.littlepage.designPattern.responsibilityChain; public interface Filter { void doFilter(Request req,Response res,FilterChain fc); }
package top.littlepage.designPattern.responsibilityChain; import java.util.ArrayList; import java.util.List; public class FilterChain implements Filter { List<Filter> filters = new ArrayList<>(); int index = -1; public FilterChain addFilter(Filter f) { filters.add(f); return this; } public void doFilter(Request req, Response res, FilterChain fc) { if (index == filters.size()-1) return; index++; filters.get(index).doFilter(req, res, fc); } }
package top.littlepage.designPattern.responsibilityChain; public class HTTPFilter implements Filter{ @Override public void doFilter(Request req, Response res,FilterChain fc) { req.setRequestStr(req.getRequestStr().replaceAll("<", "[").replaceAll(">", "]")); System.out.println("after reqHttp:"+req); fc.doFilter(req, res, fc); res.setResponseStr(res.getResponseStr().replaceAll("//", "pp")); System.out.println("after resHttp:"+res); } }
package top.littlepage.designPattern.responsibilityChain; public class Request { private String requestStr; public Request() { requestStr=""; } public Request(String requestStr) { this.requestStr = requestStr; } public String getRequestStr() { return requestStr; } public void setRequestStr(String requestStr) { this.requestStr = requestStr; } @Override public String toString() { return "Request [requestStr=" + requestStr + "]"; } }
package top.littlepage.designPattern.responsibilityChain; public class Response { private String responseStr; public Response() { responseStr=""; } public Response(String responseStr) { this.responseStr = responseStr; } public String getResponseStr() { return responseStr; } public void setResponseStr(String responseStr) { this.responseStr = responseStr; } @Override public String toString() { return "Response [responseStr=" + responseStr + "]"; } }
package top.littlepage.designPattern.responsibilityChain; public class SensitiveFilter implements Filter{ @Override public void doFilter(Request req, Response res,FilterChain fc) { req.setRequestStr(req.getRequestStr().replaceAll("sensitive", "***")); System.out.println("after reqSen:"+req); fc.doFilter(req, res, fc); res.setResponseStr(res.getResponseStr().replaceAll("mingan", "notmingan")); System.out.println("after resSen:"+res); } }
package top.littlepage.designPattern.responsibilityChain; public class Test { public static void main(String[] args) { String str="<script>//abbbmingansensitive"; Request req=new Request(str); Response res=new Response(str); FilterChain fc=new FilterChain(); fc.addFilter(new HTTPFilter()); fc.addFilter(new SensitiveFilter()); fc.doFilter(req, res, fc); } }
控制台打印如下
可以看出,首先接收端进行接收request分别执行Http进行过滤req,执行Sensitive进行过滤req
到达服务端,开始原路返回,先执行Sensitive过滤器进行过滤,然后执行Http过滤器进行过滤,
这一系列变成了一个链条,将各个过滤器穿在一起,也就成了所说的责任链设计模式。
由于是一步一步进行拦截,所以说,也可以称作拦截器模式
由此可见:原理和tomcat的filter的大致原理一样,先原线路进行依次对请求值进行过滤,然后
再对客户端的返回值进行过滤