责任链模式
顾名思义,责任链模式Chain of Responsibility Pattern为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。
这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
优点:
1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。
缺点:
1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。
使用场景:
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。
过滤器:
Filter用于在访问目标点之前或者目标执行后进行一些前置处理或者后置处理
概念:FilterChain--过滤链
解决中文乱码问题
1、定义过滤器类 直接或者间接实现Filter接口的类
public class EncoderFilter implements Filter {
private String encoding = "UTF-8";
public void init(FilterConfig config) throws ServletException {
String ss = config.getInitParameter("encoding");
if (ss != null && ss.trim().length() > 0)
encoding = ss.trim();
}
public void destroy() {
System.out.println("销毁filter对象");
}
//满足条件后执行的处理逻辑
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
// filterChain对象提供了一个方法doFilter,表示继续向后执行下一个节点
arg0.setCharacterEncoding(encoding);
arg1.setCharacterEncoding(encoding);
arg2.doFilter(arg0, arg1);//在这句之前的处理就是前置处理,在这句之后的处理就是后置处理
}
}
2、在web.xml中配置过滤器生效的条件--不是访问路径
<filter>
<filter-name>encoder</filter-name>
<filter-class>com.yan.filter.EncoderFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoder</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
Filter的生命周期:
1、Filter对象在Tomcat启动时自动进行创建
2、Filter对象创建完毕后立即执行init方法,这里有个参数FilterConfig,可以用于读取<filter>中的配置参数
3、当满足条件的请求到达时才会触发filter对象中的doFilter方法执行,这里还可以使用参数fileChain.doFilter使请求继续向后传递
/*表示当前应用中的任何内容,包括abc.jpg,abc.css,abc.do,abc.jsp
/admin/*表示当前应用中的/admin/目录下的任何请求,例如/admin/abc.do /admin/abc.jsp
*.do表示当前应用中的所有后缀为.do的请求
注意:这里没有/*.do的写法
4、Filter常驻内存
5、当服务器关闭时才会销毁Filter对象,在销毁之前执行destroy方法
6、注意:init和destroy在整个生命周期中运行且只运行一次,doFilter会使用多线程的方式运行,一般一个请求对应
一个线程
7、满多个满足条件的Filter执行时,配置序就是执行序