责任链设计模式
1.责任链模式 例如servlet中的filter struts2中的inceptor
应用场景:例如论坛的评论,在存入数据库之前要进行一系列的处理。例如影响页面显示的<>标签符号,敏感词汇等。可以通过一系列的过滤处理。
简单测试
package com.liuzhihong.simple; /** * @ClassName Main * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class MessageProcessor { public static void main(String[] args) { String mas = "我是<蜡笔小新/>~~:敏感啊啊 啊 啊啊 啊"; mas.replace("<", "[").replace("/>", "]").replace("敏感", "**"); System.out.println(mas); } }
我们这里是模拟,实际项目中处理逻辑没这么简单,可以好几百行代码,那么这么直接写肯定不满足我们面向对象的变成思想
进一步改造
接口
package com.liuzhihong.simple.inter; /** * @ClassName Filter * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public interface Filter { String doFilter(String mas); }
两种实现
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; /** * @ClassName Filter1 * @Description 模拟处理字符串把<转换为[ * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter1 implements Filter { @Override public String doFilter(String mas) { mas=mas.replace("<", "[").replace(">", "]"); return mas; } } package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; /** * @ClassName Filter2 * @Description 模拟处理敏感词汇 * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter2 implements Filter { @Override public String doFilter(String mas) { mas=mas.replace("敏感", "**"); return mas; } }
处理类
package com.liuzhihong.simple.haddler; import com.liuzhihong.simple.imp.Filter1; import com.liuzhihong.simple.imp.Filter2; import com.liuzhihong.simple.inter.Filter; /** * @ClassName Main * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class MessageProcessor { private String massage; private Filter[] filters = {new Filter1(), new Filter2()}; public String getMassage() { return massage; } public void setMassage(String massage) { this.massage = massage; } public String process() { for (Filter f : filters) { f.doFilter(massage); } return massage; } }
测试类
package com.liuzhihong.simple; import com.liuzhihong.simple.haddler.MessageProcessor; /** * @ClassName Test * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class Test { public static void main(String[] args) { String mas = "我是<蜡笔小新/>~~:敏感啊啊 啊 啊啊 啊"; MessageProcessor processor=new MessageProcessor(); processor.setMassage(mas); String newMas = processor.process(); System.out.println(newMas); } }
进一步添加需求:我们加入过滤规则,有的信息需要1,2过滤规则 但是有的信息需要1,2,3过滤规则,有的则需要1,3过滤规则 我们上面这么写显然不能满足需求了
修改代码,进一步改造
Filter接口和实现不变,添加过滤链FilteChain
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; import java.util.ArrayList; import java.util.List; /** * @ClassName FilterChain * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class FilterChain{ private List<Filter> filters=new ArrayList<Filter>(); public FilterChain addFilter(Filter f){ this.filters.add(f); return this; } public String doFilter(String mas) { for (Filter f : filters) { mas=f.doFilter(mas); } return mas; } }
修改MessageProcessor
package com.liuzhihong.simple.haddler; import com.liuzhihong.simple.imp.Filter1; import com.liuzhihong.simple.imp.Filter2; import com.liuzhihong.simple.imp.FilterChain; import com.liuzhihong.simple.inter.Filter; /** * @ClassName Main * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class MessageProcessor { private Filter[] filters = {new Filter1(), new Filter2()}; private String massage; private FilterChain filterChain; public FilterChain getFilterChain() { return filterChain; } public void setFilterChain(FilterChain filterChain) { this.filterChain = filterChain; } public String getMassage() { return massage; } public void setMassage(String massage) { this.massage = massage; }
//把处理过滤交给FilteChain处理 public String process() { massage=filterChain.doFilter(massage); return massage; } }
测试类:
package com.liuzhihong.simple; import com.liuzhihong.simple.haddler.MessageProcessor; import com.liuzhihong.simple.imp.Filter1; import com.liuzhihong.simple.imp.Filter2; import com.liuzhihong.simple.imp.FilterChain; /** * @ClassName Test * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class Test { public static void main(String[] args) { String mas = "我是<蜡笔小新/>~~:敏感啊啊 啊 啊啊 啊"; FilterChain filterChain=new FilterChain(); filterChain.addFilter(new Filter1()).addFilter(new Filter2());//我们可以根据实际需求添加需要的过滤即可满足需求 MessageProcessor processor=new MessageProcessor(); processor.setMassage(mas); processor.setFilterChain(filterChain); String newMas = processor.process(); System.out.println(newMas); } }
如果我们把FilteChain看成一个整体,假如我们的信息需要过滤过滤链1中的和过滤链中过滤所有过滤规则 只需要过滤链也实现Filter接口即可
这是因为对于过滤链中的addFilter方法 Filter可以是过滤链也可以是过滤规则 他们都实现了Filter ,例如下面Filterchain1有两条规则,FilteChain2有两条规则
FilterChain1.add(FilterChain2) 这时候FilterChain1的List中的元素有3个 :过滤规则Filter1,过滤规则Filter2,过滤链FilterChain2,在运行到String newMas = processor.process();时候会调用通过
FilteChain的doFilter方法,这是后传入的是对象filterChain1。filterChain1中的List分别执行他们doFilter方法。Filter1,Filter2直接执行过滤massage,filterchain2执行doFilter方法时候,又调用FilteChain
的doFilter方法,这时候传入的是对象filterChain2,分别执行Filter3,Filter4的doFilter方法完成过滤。
修改代码,进一步改造
添加过滤规则Filter3去除信息中的空格
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; /** * @ClassName Filter3 * @Description 去除空格 * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter3 implements Filter { @Override public String doFilter(String mas) { mas=mas.trim().replace(" ", ""); return mas; } }
添加过滤规则4在尾部添加感叹号
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; /** * @ClassName Filter4 * @Description 在尾部加感叹号 * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter4 implements Filter { @Override public String doFilter(String mas) { mas = mas + "!"; return mas; } }
测试类
package com.liuzhihong.simple;
import com.liuzhihong.simple.haddler.MessageProcessor;
import com.liuzhihong.simple.imp.*;
/**
* @ClassName Test
* @Description
* @Author 刘志红
* @Date 2019/3/11
**/
public class Test {
public static void main(String[] args) {
String mas = "我是<蜡笔小新/>~~:敏感啊啊 啊 啊啊 啊";
FilterChain filterChain1=new FilterChain();
filterChain1.addFilter(new Filter1()).addFilter(new Filter2());
FilterChain filterChain2=new FilterChain();
filterChain2.addFilter(new Filter3()).addFilter(new Filter4());
//FilteChain2中的过滤规则添加FilterChain1中
filterChain1.addFilter(filterChain2);
MessageProcessor processor=new MessageProcessor();
processor.setMassage(mas);
processor.setFilterChain(filterChain1);
String newMas = processor.process();
System.out.println(newMas);
}
}
进一步改造 假如我们web项目中的请求和响应回来的信息都需要过滤
浏览器发出求情 通过过滤规则1 2 3 4的过滤 然后服务器接收响应 通过过滤规则4 3 2 1的过滤(图中的5 6 7 8)
代码如下:
过滤规则接口
package com.liuzhihong.simple.inter; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Filter * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public interface Filter { void doFilter(Request request, Response response); }
实现类过滤规则1
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Filter1 * @Description 模拟处理字符串把<转换为[ * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter1 implements Filter { @Override public void doFilter(Request request, Response response) { String requestMassage = request.getRequestMessage().replace("<", "[").replace(">", "]"); requestMassage+="--request:filter1--"; request.setRequestMessage(requestMassage); } }
实现类过滤规则2
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Filter2 * @Description 模拟处理敏感词汇 * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter2 implements Filter { @Override public void doFilter(Request request, Response response) { String requestMessage = request.getRequestMessage().replace("敏感", "**"); requestMessage+="--request:filter2--"; request.setRequestMessage(requestMessage); } }
实现类3过滤链
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; import java.util.ArrayList; import java.util.List; /** * @ClassName FilterChain * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class FilterChain implements Filter{ private List<Filter> filters=new ArrayList<Filter>(); public FilterChain addFilter(Filter f){ this.filters.add(f); return this; } public void doFilter(Request request, Response response) { for (Filter f : filters) { f.doFilter(request, response); } } }
模拟请求和响应
package com.liuzhihong.simple.web; /** * @ClassName Server * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class Request { private String requestMessage; public String getRequestMessage() { return requestMessage; } public void setRequestMessage(String requestMessage) { this.requestMessage = requestMessage; } } package com.liuzhihong.simple.web; /** * @ClassName Response * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class Response { private String responseMessage; public String getResponseMessage() { return responseMessage; } public void setResponseMessage(String responseMessage) { this.responseMessage = responseMessage; } }
测试类
package com.liuzhihong.simple; import com.liuzhihong.simple.imp.*; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Test * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class Test { public static void main(String[] args) { String mas = "我是<蜡笔小新/>~~:敏感啊啊 啊 啊啊 啊"; Request request=new Request(); request.setRequestMessage(mas); Response response=new Response(); FilterChain filterChain=new FilterChain(); filterChain.addFilter(new Filter1()).addFilter(new Filter2()); filterChain.doFilter(request, response); System.out.println(request.getRequestMessage()); } }
上面是请求添加过滤,那么响应怎么添加呢 如果我们直接在Filter1 Fiter2中添加的对响应的处理的话。执行结果如下:1 2 3 4。显然和我们想要的结果不符合,这也和实际逻辑矛盾 还没有响应过来信息就处理了---
那么我们该怎么处理呢 ,有点类似递归,一层一层进入,到底了满足一个条件然后一层一层退出
进一步改进代码:模拟请求和模拟响应类不变
过滤规则接口:
package com.liuzhihong.simple.inter; import com.liuzhihong.simple.imp.FilterChain; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Filter * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public interface Filter { void doFilter(Request request, Response response, FilterChain filterChain); }
实现类
package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Filter1 * @Description 模拟处理字符串把<转换为[ * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter1 implements Filter { @Override public void doFilter(Request request, Response response,FilterChain filterChain) { String requestMassage = request.getRequestMessage().replace("<", "[").replace(">", "]"); requestMassage+="--request:filter1--"; request.setRequestMessage(requestMassage); filterChain.doFilter(request, response, filterChain); String responseMessage = response.getResponseMessage().replace("<", "[").replace(">", "]"); responseMessage+="--response:filter1--"; response.setResponseMessage(responseMessage); } } package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Filter2 * @Description 模拟处理敏感词汇 * @Author 刘志红 * @Date 2019/3/11 **/ public class Filter2 implements Filter { @Override public void doFilter(Request request, Response response,FilterChain filterChain) { String requestMessage = request.getRequestMessage().replace("敏感", "**"); requestMessage+="--request:filter2--"; request.setRequestMessage(requestMessage); filterChain.doFilter(request, response, filterChain); String responseMessage = response.getResponseMessage().replace("敏感", "**"); responseMessage+="--response:filter2--"; response.setResponseMessage(responseMessage); } } package com.liuzhihong.simple.imp; import com.liuzhihong.simple.inter.Filter; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; import com.sun.xml.internal.bind.v2.model.core.ID; import java.util.ArrayList; import java.util.List; /** * @ClassName FilterChain * @Description 过滤链 * @Author 刘志红 * @Date 2019/3/11 **/ public class FilterChain implements Filter{ private List<Filter> filters=new ArrayList<Filter>(); private int index=0; public FilterChain addFilter(Filter f){ this.filters.add(f); return this; } public void doFilter(Request request, Response response,FilterChain filterChain) { if (index==filters.size())return; Filter filter = filters.get(index); index++; filter.doFilter(request, response, filterChain); } }
测试类
package com.liuzhihong.simple; import com.liuzhihong.simple.imp.*; import com.liuzhihong.simple.web.Request; import com.liuzhihong.simple.web.Response; /** * @ClassName Test * @Description * @Author 刘志红 * @Date 2019/3/11 **/ public class Test { public static void main(String[] args) { String requestMas = "我是<request/>~~:敏感"; String responseMas="我是<response/>~~:敏感"; Request request=new Request(); request.setRequestMessage(requestMas); Response response=new Response(); response.setResponseMessage(responseMas); FilterChain filterChain=new FilterChain(); filterChain.addFilter(new Filter1()).addFilter(new Filter2()); filterChain.doFilter(request, response,filterChain); System.out.println(request.getRequestMessage()); System.out.println(response.getResponseMessage()); } }
Servlet之Filter原理:
容器把收到的请求和返回的响应封装成对应的Request,Response类,根据web.xml中Filter的配置信息(包括过滤规则的实现类和拦截域名)以及我们写的Filter(过滤规则),把请求,响应需要拦截处理的过滤规则存入FilterChain中。后续原理和上面 一样了就。
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!