Filter体现职责链模式

1. 前言

Filter—Filter 技术是servlet2.3 新添加?的功能。完毕的流程:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对server响应进行后处理。

Filter体现了一种职责琏模式。那么他是怎样体现的呢?

2. 职责链模式

在详细的解释这个之前先看看职责链模式的定义:使多个对象都有机会处理请求 ,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一个链,并沿着这条链传递请求,直到有一个对象处理它为止。

对于Filter而言就是,请求传给详细的web资源(比方jsp/servlet)之前要经过Filter的预处理,在web资源处理完毕返回给client之前也要被Filter处理一遍。就好比以下的这样的图

当创建了多个Filter之后,client传来一个Request请求,它就面对着这一个Filter链,职责琏模式就体如今这里。这个请求会在这个Filter链上一个一个被传递下去对它进行预处理,处理完毕之后就传给下一个Filter直到最后一个,然后才交给web进行对应的訪问和处理。它的uml图(并非完毕的结构图,仅仅是体现职责琏模式的结构图)例如以下:

一个Filter接口定义了三个方法:init()(初始化方法);destroy()(销毁方法);doFilter()(核心的职责方法);两个详细类实现了Filter接口:ConcreteFilter1和ConcreteFilter2;

一个FilterChain接口定义了一个方法:doFilter();一个详细的实现类ConcreteFilterChain;

当中FilterChain基本的作用是完毕找到下一个Filter。

3. 详细的实现

以下是对于上面结构图的一个简单实现,帮助我们理解一下Filter体现的职责琏模式。

ConcreteFilter1类

package com.test.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * ConcreteFilter1类
 * @author pf
 *
 */
public class ConcreteFilter1 implements Filter {

//	private String encoding;

	@Override
	public void destroy() {
		System.out.println("ConcreteFilter1()的destroy()运行");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("----ConcreteFilter1()的chain.doFilter()调用之前:对用户请求(request)进行预处理");
		//继续运行
		//后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
		chain.doFilter(request, response);
		System.out.println("ConcreteFilter1()的chain.doFilter()调用之后:对server响应(response)进行后处理");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
//		System.out.println("init開始");
//		this.encoding = filterConfig.getInitParameter("encoding");
//		System.out.println("init得到encoding:" + encoding);
		System.out.println("ConcreteFilter1()的init()方法调用");

	}

}

ConcreteFilter2类

package com.test.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 採用Filter统一处理字符集
 * @author pf
 *
 */
public class ConcreteFilter2 implements Filter {

//	private String encoding;
	@Override
	public void destroy() {
		System.out.println("ConcreteFilter2()的destroy()运行");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("ConcreteFilter2()的chain.doFilter()调用之前");
//		request.setCharacterEncoding(encoding);
		//后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
		chain.doFilter(request, response);
		System.out.println("ConcreteFilter2()的chain.doFilter()调用完毕");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
//		System.out.println("init開始");
//		this.encoding = filterConfig.getInitParameter("encoding");
//		System.out.println("init得到encoding:" + encoding);
		System.out.println("ConcreteFilter2()的init()方法调用");
	}

}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<filter>
		<filter-name>ConcreteFilter1</filter-name>
		<filter-class>com.test.filter.ConcreteFilter1</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>ConcreteFilter1</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
		<filter>
		<filter-name>ConcreteFilter2</filter-name>
		<filter-class>com.test.filter.ConcreteFilter2</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>ConcreteFilter2</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>

</web-app>

完毕之后启动server,我这里是tomcat,会显演示样例如以下信息:

说明在启动server的时候就会创建我们的Filter对象

随便訪问一个页面再次查看console

关闭server:说明在关闭server的时候销毁创建的Filter对象

从上面的运行结果再来看一下Filter。我们设置了两个Filter,各自是ConcreteFilter1和ConcreteFilter2.依照我们在web.xml中配置的顺序来运行,先运行了ConcreteFilter1,在运行ConcreteFilter2.

可是注意观察,他们在真正调用chain的doFilter方法之后的调用顺序正好相反了。所以我们从这个结果能够看到Filter的运行顺序是遵循”后进先出”的原则。现将传来的url依照配置中的顺序进行预处理,可是确实先依照相反的filter顺序运行处理好的请求。

以下是讲他的调用过程画了一个时序图:

3. 总结:

通过上面代码运行的结果来看,Filter非常好的实现了职责链模式,对于不论什么一个请求来讲都有一条Filter链能够处理它,详细是哪一个处理了我们事实上并不知道可是在到达servlet之前就是已经给我们处理好了,这样子就非常好的做到了对象之间的解耦和。

时间: 2024-08-25 11:44:50

Filter体现职责链模式的相关文章

Filter技术+职责链模式

Filter是一个过滤器,存在Web客户端与请求的资源之间,这里的资源可以说是jsp或servlet.它的作用就是在请求达到资源之前,先对请求进行预处理,并且也可以对servlet处理后的response进行修改. Filter可以是有很多个,当一个个Filter组合成起来,就形成了一个FilterChain.也就是我们说的过滤链,这个过滤链处理的过程,就是我们前面学的职责链模式的一个体现. 下面是一个修改字符串的小例子: 1.FilterChain内包含各个子filter,利用dofilter

重温设计模式(三)——职责链模式(chain of responsibility)

一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所以希望各位多多指教. 二. 什么是链 文章伊始,先让我们了解这个最基本的概念,什么是链. 我给链下了这样的定义: 1. 链是一系列节点的集合. 2. 链的各节点可灵活拆分再重组. 三. 何为职责链 职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条

行为型模式之职责链模式

概述 很多情况下,在一个软件系统中可以处理某个请求的对象不止一个,例如SCM系统中的采购单审批,主任.副董事长.董事长和董事会都可以处理采购单,他们可以构成一条处理采购单的链式结构,采购单沿着这条链进行传递,这条链就称为职责链.职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并让请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递

设计模式解密(20)- 职责链模式

1.简介 定义:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止. 主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了. 本质:分离职责,动态组合. 分离职责:分离职责是前提,只有先把复杂功能分开,拆分成很多的步骤和小的功能处理,然后才能合理规划和定义职责类. 动态组合:动态组合是精华,因为要实现请求对象和处理

java设计模式之职责链模式

[学习难度:★★★☆☆,使用频率:★★☆☆☆] "一对二","过","过"--这声音熟悉吗?你会想到什么?对!纸牌.在类似"斗地主"这样的纸牌游戏中,某人出牌给他的下家,下家看看手中的牌,如果要不起上家的牌则将出牌请求再转发给他的下家,其下家再进行判断.一个循环下来,如果其他人都要不起该牌,则最初的出牌者可以打出新的牌.在这个过程中,牌作为一个请求沿着一条链在传递,每一位纸牌的玩家都可以处理该请求.在设计模式中,我们也有一种专

LindDotNetCore~职责链模式的应用

回到目录 职责链模式 它是一种设计模块,主要将操作流程与具体操作解耦,让每个操作都可以设置自己的操作流程,这对于工作流应用是一个不错的选择! 下面是官方标准的定义:责任链模式是一种设计模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任. 职责链模式组成 三大对象 命令处理 处理流程 命令上下文

[设计模式]&lt;6&gt;. C++与职责链模式(chain of rsponsibility pattern)

默默地EEer,原文地址: http://www.cnblogs.com/hebaichuanyeah/p/5625233.html 职责链模式指使多个对象多有机会处理请求,避免请求发送者和接受者的耦合关系. 将这些接受处理的对象连成一条链,并沿着该链处理请求. 一个传说中的应用情景: 假如去政府部门办事,遇到了打字员小丽,在打LOL的小张以及主任老李,互相踢皮球推脱. #include <iostream> using namespace std; class Handler { prote

职责链模式

1.职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,指导有一个对象处理它为止. 2.优点:(1).当客户提交一个申请时,请求是沿链传递直至有一个对象负责处理它位置.在客户端根本不需要知道是谁做的处理.(2).简化对象的相互连接,它们仅需要保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用.(3).可以随时增加或者修改处理一个请求的结构.增强了给对象纸牌职责的灵活性. 3.注意:一个请求极有可能到链的末端都

设计模式之行为型模式—— 3.5 职责链模式

<?php /**  * 3.5 职责链模式  *  定义:  *  使多个对象都有机会处理请求,从而避免请求的  *  发送者和接受者直接的耦合关系.将这个对象连  *  成一条链,并沿着这条链传递该请求,直到有一  *  个对象处理它为止.  *  角色:  *  1. 抽象Handler类  *  职责:定义一个处理请示的接口.  *  2. 具体Handler类  *  职责:具体处理者类,处理它所负责的请求  *    ,它可访问它的后继者,如果可处理  *    该请求,就处理之,否