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中。后续原理和上面 一样了就。
来源:oschina
链接:https://my.oschina.net/u/4263469/blog/3617796