一、什么是责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式。其核心思想是将请求的发送者和接收者解耦,通过一个中介链来传递请求,使得多个对象都有可能接收请求,从而避免请求发送者和接收者之间的耦合关系。
二、责任链模式的角色
-
抽象处理者(Handler)角色:作为责任链模式的核心,这个接口定义了统一的处理请求的方法,并定义了如何将请求传递给下一个处理者。
-
具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求。如果可以处理请求,则直接处理;否则,将请求传递给下一个处理者。
三、责任链模式的典型应用
- 多层拦截器:在Web开发中,可以使用责任链模式来实现多层拦截器,每个拦截器都可以对请求进行预处理或后处理,实现多层拦截的功能 。
-
可改变顺序的处理者:必须按顺序执行多个处理者,尤其在运行时执行顺序可改变时,可以使用责任链模式。
- 多个对象可以处理请求:当系统中存在多个对象,每个对象都可能处理同一个请求,但具体由哪个对象处理应在运行时决定。
- 避免复杂的条件判断:当请求需要根据多个条件进行不同的处理,可以使用责任链模式,避免使用嵌套的if-else语句,使代码更加简洁易读。
四、责任链模式在FilterChain中的应用
责任链模式在FilterChain
中的应用是Java Servlet API中一个经典的例子。在这种应用中,每个过滤器(Filter)都有机会处理HTTP请求,并且可以决定是否将请求传递给链中的下一个过滤器或目标资源。以下是每个类在责任链模式中的角色以及一个简单的代码案例
-
抽象处理者(Handler):
- 在
FilterChain
中,Filter
接口扮演了抽象处理者的角色。它定义了所有过滤器必须实现的doFilter
方法,该方法接收请求(ServletRequest)、响应(ServletResponse)和一个FilterChain
实例 。
- 在
-
具体处理者(Concrete Handler):
- 具体过滤器类实现了
Filter
接口。在doFilter
方法中,每个过滤器可以对请求和响应进行处理,然后通过调用FilterChain
的doFilter
方法将请求传递给链中的下一个过滤器 。
- 具体过滤器类实现了
-
客户端(Client):
- 在这个上下文中,客户端可以是任何发起HTTP请求的实体,如Web浏览器。客户端发送请求到Servlet容器,该容器负责构建过滤器链并处理请求 。
-
FilterChain(责任链):
FilterChain
接口定义了doFilter
方法,用于调用链中的下一个过滤器或最终的资源(如Servlet)。FilterChain
的实现类负责管理过滤器链的执行顺序 。
以下是一个简单的代码案例,展示了两个过滤器如何在FilterChain
中按顺序工作 :
1.定义第一个过滤器:LoggingFilter:
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("LoggingFilter 初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("LoggingFilter: 请求开始...");
// 执行下一个过滤器或目标资源
chain.doFilter(request, response);
System.out.println("LoggingFilter: 响应返回...");
}
@Override
public void destroy() {
System.out.println("LoggingFilter 销毁");
}
}
2.定义第二个过滤器:AuthenticationFilter:
public class AuthenticationFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("AuthenticationFilter 初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
Cookie[] cookies = httpRequest.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
System.out.println("Found cookie: " + cookie.getName() + "=" + cookie.getValue());
}
}
// 继续执行过滤器链
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("AuthenticationFilter 销毁");
}
}
3.定义目标资源:DemoServlet:
public class DemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("DemoServlet: 处理请求...");
resp.getWriter().write("Hello, FilterChain!");
}
}
在这个例子中,LoggingFilter
和AuthenticationFilter
是具体处理者,它们实现了Filter
接口,并在doFilter
方法中处理请求。FilterChain
的实例通过chain.doFilter(request, response)
调用传递请求给下一个过滤器或最终的Servlet资源。当访问DemoServlet
时,过滤器链将按顺序执行,首先执行LoggingFilter
,然后是AuthenticationFilter
,最后是DemoServlet
处理请求 。