过滤器模式,顾名思义,就是过滤对象用的,对需要过滤的对象,进行一些验证,或者加某些特定信息,或者删减信息都可以。如果你想定义多个过滤规则,那么就需要定义多个过滤器,一般每个过滤器只实现一种规则。然后多个过滤器会连在一起,形成一个过滤器链,想想我们的servlet的过滤器,其实就是这样的,下面我就根据servlet过滤器实现方式,来模拟一下过滤器的模式:

  1、首先定义两个需要过滤的对象,

  Request:

  1. package com.hd.filter;
  2. public class Request {
  3. private String requestStr;
  4. public Request(String requestStr) {
  5. this.requestStr = requestStr;
  6. }
  7. public String getRequestStr() {
  8. return requestStr;
  9. }
  10. public void setRequestStr(String requestStr) {
  11. this.requestStr = requestStr;
  12. }
  13. public void addStr(String str){
  14. this.requestStr += str;
  15. }
  16. }

  Response:

  1. package com.hd.filter;
  2. public class Response {
  3. private String ResponseStr;
  4. public Response(String responseStr) {
  5. ResponseStr = responseStr;
  6. }
  7. public String getResponseStr() {
  8. return ResponseStr;
  9. }
  10. public void setResponseStr(String responseStr) {
  11. ResponseStr = responseStr;
  12. }
  13. public void addStr(String str){
  14. this.ResponseStr += str;
  15. }
  16. }

 

  2、然后需要定义一个filter接口:

  1. package com.hd.filter;
  2. public interface Filter {
  3. void doFilter(Request request, Response response, FilterChain filterChain);
  4. }

  

  3、接着我们再定义一个过滤器链FilterChain,用来将多个过滤器有序的链起来:

  1. package com.hd.filter;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class FilterChain {
  5. private List<Filter> filterChains = new ArrayList<Filter>();
  6. public static FilterChain build(){
  7. return new FilterChain();
  8. }
  9. public FilterChain addFilter(Filter filter){
  10. this.filterChains.add(filter);
  11. return this;
  12. }
  13. public FilterChain removeFilter(Filter filter){
  14. this.filterChains.remove(filter);
  15. return this;
  16. }
  17. }

 

  4、下面就是定义具体的filter实现了:

  1. package com.hd.filter;
  2. public class HTMLFilter implements Filter {
  3. @Override
  4. public void doFilter(Request request, Response response, FilterChain filterChain) {
  5. System.out.println("HTMLFilter Request");
  6. request.addStr("-HTML-");
  7. filterChain.doFilter(request, response);    //这里是第一个重点的地方,只有这样设计,request才可以按照正序执行过滤,response按照倒序执行过滤
  8. response.addStr("-HTML-");
  9. System.out.println("HTMLFilter Response");
  10. }
  11. }

 

  1. package com.hd.filter;
  2. public class SensitiveFilter implements Filter {
  3. @Override
  4. public void doFilter(Request request, Response response, FilterChain filterChain) {
  5. System.out.println("SensitiveFilter Request");
  6. request.addStr("-Sensitive-");
  7. filterChain.doFilter(request, response);
  8. response.addStr("-Sensitive-");
  9. System.out.println("SensitiveFilter Response");
  10. }
  11. }

 

  1. package com.hd.filter;
  2. public class LowerUpcaseFilter implements Filter {
  3. @Override
  4. public void doFilter(Request request, Response response, FilterChain filterChain) {
  5. System.out.println("LowerUpcaseFilter Request");
  6. request.addStr("-LowerUpcase-");
  7. filterChain.doFilter(request, response);
  8. response.addStr("-LowerUpcase-");
  9. System.out.println("LowerUpcaseFilter Response");
  10. }
  11. }

 

  5、下面我们还差一个重要的点,就是如何把所有的过滤器串起来,还按照顺序往下执行。如果你有经过思考后的话,不难想到应该是在FilterChain的 doFilter 方法里做文章:

  1. private int index =0;
  2. public void doFilter(Request request, Response response){
  3. if(index < filterChains.size()){
  4. filterChains.get(index++).doFilter(request, response, this);
  5. }else{
  6. return;
  7. }
  8. }

  定义一个变量,用来标记当前需要处理的是哪个过滤器,这是第二个重点

  6、最后写下测试代码:

  1. package com.hd.filter;
  2. public class TestFilter {
  3. public static void main(String[] args){
  4. FilterChain filterChain = FilterChain.build();
  5. filterChain.addFilter(new HTMLFilter());
  6. filterChain.addFilter(new SensitiveFilter());
  7. filterChain.addFilter(new LowerUpcaseFilter());
  8. Request request = new Request("request");
  9. Response response = new Response("response");
  10. filterChain.doFilter(request, response);
  11. System.out.println(request.getRequestStr());
  12. System.out.println(response.getResponseStr());
  13. }
  14. }

 

  运行结果如下:

  1. HTMLFilter Request
  2. SensitiveFilter Request
  3. LowerUpcaseFilter Request
  4. LowerUpcaseFilter Response
  5. SensitiveFilter Response
  6. HTMLFilter Response
  7. request-HTML--Sensitive--LowerUpcase-
  8. response-LowerUpcase--Sensitive--HTML-

 

  如果你写过递归算法的话,应该会和我有同感,感觉过滤器有点像递归算法,一层层的往下套,然后执行到最后一层的之后,再一个个原路返回。

  过滤器在spring中也有重点运用,AOP切面的实现方式就用到了过滤器模式,后面有机会我会介绍的。

  未完待续。。。

版权声明:本文为xiexin2015原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xiexin2015/p/9037865.html