一.逻辑来源:
1.chain.doFilter:
filter-链路,web.xml里面配置几个,几个串联起来后形成链路进行逻辑执行
chain.doFilter将请求交给过滤链路执行下一个filter,如果web.xml中没有下一个filter,
执行的就是你自己的资源。
例如web.xml中:
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/output.jsp</url-pattern>
</filter-mapping>
output.jsp就是自己的资源。
2.举例:
校验用户注册输入的参数,通过web.xml filter请求,拦截请求后会根据web.xml的过滤顺序来执行逻辑,
如果拦截的请求在处理业务上出现问题可以转发的错误页面或者重定向而不需要继续走web.xml的逻辑。
解释一下
重定向和转发:
重定向服务器会重新提供给客户端一个url,让用户去请求,转发就是服务器直接获取资源
3.配置:
<filter>
<description></description>
<display-name>encodefilter</display-name>
<filter-name>encodefilter</filter-name>
<filter-class>servletbean.encodefilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GB2312</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodefilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<description></description>
<display-name>myfilter</display-name>
<filter-name>myfilter</filter-name>
<filter-class>servletbean.myfilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/output.jsp</url-pattern>
</filter-mapping>
4.代码
逻辑:请求会根据web.xml配置的filter进行逻辑流程的执行,如果出现了异常,那么将会跳转值错误页面,
或者重定向到另一个后台逻辑进行处理。
例如:
登录功能:
当用户登录到管理中心后台服务,用户会携带token,那么通过加密平台提供的私钥进行token解密,
并对token进行解析,若token解析后为未登录状态,那么重定向到统一认证平台获取登录后的token,
如果登录用户携带的token为登录状态,那么走chain.filter(request,responsed)这个过滤器
1)
public class encodefilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if(request.getCharacterEncoding()==null) {
System.out.println(encoding);
//设置编码集
request.setCharacterEncoding(encoding);
}
//可以直接到web.xml下一个中filter链路d
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
this.config=fConfig;
//获取编码集
encoding=fConfig.getInitParameter("encoding");
}
}
(2)
public class myfilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html");
response.setCharacterEncoding("GB2312");
String name="";
String age="";
int ageCheck;
name=request.getParameter("name");
age=request.getParameter("age");
if(name==null||name==""||name==" "||age==null) {
//此处也可以为重定向
request.getRequestDispatcher("/error.jsp").forward(request, response);
return;
}
else{
try {
ageCheck=Integer.parseInt(age);
}catch(Exception e){
//参数必须能转型为数字类型
request.getRequestDispatcher("/error.jsp").forward(request, response);
return;//如果是错误页面就到erroroutput.jsp中
}
}
//这里表示是正确的,也就是说,他回去找下一个链,但是它下面已经没有了,所以就会去跳转页面了,此跳转的页面就是action="output.jsp"了
chain.doFilter(request, response);
}
}
二.责任链:
1.概念:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,
并沿着这条链传递该请求。
这些对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,
直到链上的某一个对象决定处理此请求。
1.1模式的结构
责任链模式的结构总包括两种角色:
(1)处理者(Handler):处理者是一个接口,负责规定具体处理者处理用户请求的方法,
以及具体处理者设置后继对象的方法。
(2)具体处理者(ConcreteHandler):具体处理者是实现处理者接口的类的实例。
具体处理者通过调用处理者接口规定的方法处理用户的请求,即在接到用户的请求后,
处理者将调用接口规定的方法,在执行该方法的过程中,如果发现能处理用户的请求,
就处理有关数据,否则就反馈无法处理的信息给用户,然后将用户的请求传递给自己的后继对象。
1.2责任链模式的优点
(1)责任链中的对象只和自己的后继是低耦合关系,和其他对象毫无关联,这使得编写处理者对象以及创建责任链变得非常容易。
(2)当在处理者中分配职责时,责任链给应用程序更多的灵活性。
(3)应用程序可以动态地增加、删除处理者或重新指派处理者的职责。
(4)
应用程序可以动态地增加、删除处理者或重新指派处理者的职责。
(5)应用程序可以动态地改变处理者之间的先后顺序。
(6)使用责任链的用户不必知道处理者的信息,用户不会知道到底是哪个对象处理了它的请求。
1.3适合使用责任链模式的情景
(1)有许多对象可以处理用户的请求,希望程序在运行期间自动确定处理用户的那个对象。
(2)希望用户不必明确指定接受者的情况下,向多个接受者的一个提交请求。
(3)程序希望动态制定可处理用户请求的对象集合。
2.代码
version1:
public interface Handler {
public abstract void handleRequest(String data);
public abstract void setNextHandler(Handler handler);
}
public class A implements Handler{
//存放当前处理者后继的Handler接口变量
private Handler handler;
//存放校验数据
private ArrayList<String>dataList;
A(){
dataList= new ArrayList<String>();
dataList.add("1");
dataList.add("2");
}
//校验的参数
public void handleRequest(String data){
if(numberList.contains(data))
System.out.println("data是1或者2");
else{
System.out.println("data不是1或者2");
if(handler != null)
//将请求传递给下一个处理者(交给下一个对象进行处理)
handler.handleRequest(data);
}
}
public void setNextHandler(Handler handler){
this.handler = handler;
}
}
public class Test{
private Handler A,B,C; //责任链上的对象 B,C的创建和A相同
public void createChain(){ //建立责任链
A= new A();
B= new B();
C= new C();
A.setNextHandler(B);
B.setNextHandler(C);
}
public void reponseClient(String data){ //响应用户的请求
beijing.handleRequest(data);
}
public static void main(String args[]){
Tes test= new Test();
test.createChain();
//为什么传3?考虑下,会被BC处理掉么?
test.reponseClient("3");
}
}