设计模式:Filter+Servlet+反射

Posted strugglinggirl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式:Filter+Servlet+反射相关的知识,希望对你有一定的参考价值。

传统设计

分类管理需要:增加,删除,编辑,修改,查询5个服务端功能。 

一个路径对应一个Servlet的思路,就需要设计5个Servlet类,并且在web.xml中配置5个路径。

CategoryAddServlet
CategoryDeleteServlet
CategoryEditServlet
CategoryUpdateServlet
CategoryListServlet
改进设计

每种实体类,对应了一个Servlet,而不是对应了5个,这样首先从Servlet数量上来讲,就大大的减少了。

原理流程图

那么是如何做到一个CategoryServlet类,就能完成本来需要5个Servlet类才能完成的功能的呢?

思路:(1)要有Servlet类的类名className,才能进入对应的Servlet类。

           (2)要有方法名method,才能通过反射机制获得该Method对象,调用此方法。

关键在于访问路径的设计:

借助流程图来分析,为什么访问admin_category_list的时候,CategoryServlet的list()方法会被调用。

 在web.xml配置文件中,让所有的请求【/*】都会经过BackServletFilter

技术图片
<filter>
    <filter-name>BackServletFilter</filter-name>
    <filter-class>tmall.filter.BackServletFilter</filter-class>
</filter>
 
<filter-mapping>
    <filter-name>BackServletFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
View Code

*************************************************

1、过滤器BackServletFilter要完成什么事?

(1)获取访问路径的"/admin_category_list"字符串

技术图片
String contextPath=request.getServletContext().getContextPath();

String uri = request.getRequestURI();

uri =StringUtils.remove(uri, contextPath);
View Code

(2)对以"/admin_"开头的路径,进行判断。

如果条件成立,实施步骤(3、4、5)。

不成立的,进行下一个路径的拦截。

技术图片
       if(uri.startsWith("/admin_")){     
            //(3)
            //(4)
            //(5)
            return;
        }        
        chain.doFilter(request, response);
View Code

(3)获取访问路径中的category和list这两个字符串

技术图片
String  servletName=StringUtils.substringBetween(uri,"_", "_");

String method=StringUtils.substringAfterLast(uri,"_" );
View Code

(4)确定要进入的Servlet类类名和要调用的方法名

技术图片
String servletPath = servletName + "Servlet";
String method = StringUtils.substringAfterLast(uri,"_" );
View Code

(5)服务端跳转到指定的Servlet,同时在请求中传递一个参数

技术图片
request.setAttribute("method", method);

req.getRequestDispatcher("/" + servletPath).forward(request, response);
View Code

 

2、指定的Servlet类(这里指CategoryServlet)要完成什么事?

(1)获取请求中的参数

技术图片
String method = (String) request.getAttribute("method");
View Code

(2)根据参数创建Method对象m

技术图片
 Method m = this.getClass().getMethod(method);
View Code

(3)调用m

技术图片
m.invoke(this);
View Code

 

 

技术图片

 3、根据调用m后返回的结果,进行不同的处理。

String redirect = m.invoke(this);

(1)客户端跳转

if(redirect.startsWith("@"))

    response.sendRedirect(redirect.substring(1));

(2)服务端跳转

else

    request.getRequestDispathcher(redirect).forword(request,response);

(3)输出字符串

esle if(redirect.startsWith("%"))

    response.getWriter().print(redirect.substring(1));

 

注意:

(1)服务端跳转的话,路径不变,跳转前后还是同一个请求,

可以以此获得请求中的参数或者session值。

(2)客户端跳转的话,路径改变,请求改变。

(3)有数值要传递的话优先服务端跳转。

在CategoryServlet类中,有5种方法可供调用,返回的结果各不相同。

1、add()方法,最后要跳转到/admin_category_list路径         

return  ——>@admin_category_list

2、delete()方法,最后要跳转到/admin_category_list路径     

return  ——>@admin_category_list

3、edit()方法,最后要跳转到edit.jsp页面                             

return   ——>admin/editCategory.jsp

4、update()方法,最后要跳转到/admin_category_list路径     

return  ——>@admin_category_list

5、list()方法,最后要跳转到list.jsp页面                                

return   ——>admin/listCategory.jsp

 

注意:BaseBackServlet类重写了service()方法,

2和3所说的重复性代码被封装在这个方法里。

 

 

 

以上是关于设计模式:Filter+Servlet+反射的主要内容,如果未能解决你的问题,请参考以下文章

filter和interceptor的区别

透过源码学习设计模式1—Servlet Filter和责任链模式

Dubbo filter扩展

servlet单例模式以及servlet的请求流程

servlet和filter的区别

过滤器(Filter)与拦截器(Interceptor)的区别