- 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和其他框架中實現過濾器和攔截器使用的較為普遍,並且十分巧妙.
[火星人 ] Java設計模式:責任鏈已經有434次圍觀