《JAVA与模式》第13天―门面模式 (三)

2014-11-24 08:27:06 · 作者: · 浏览: 1
Post(HttpServletRequest request, HttpServletResponse response)
11. throws ServletException, IOException {
12.
13.
14. }
15.
16. }


  可以看出doGet与doPost方法有两个参数,参数类型是接口HttpServletRequest与接口HttpServletResponse,那么从Tomcat中传递过来的真实类型到底是什么呢?通过debug会发现,在真正调用TestServlet类之前,会经过很多Tomcat中的方法。如下图所示


  注意红色方框圈中的类,StandardWrapperValue类中的invoke方法225行代码如下:
[java]
1. filterChain.doFilter
2. (request.getRequest(), response.getResponse());


  在StandardWrapperValue类中并没有直接将Request对象与Response对象传递给ApplicationFilterChain类的doFilter方法,传递的是RequestFacade与ResponseFacade对象,为什么这么说呢,看一下request.getRequest()与response.getResponse()方法就真相大白了。
Request类
[java]
1. public HttpServletRequest getRequest() {
2. if (facade == null) {
3. facade = new RequestFacade(this);
4. }
5. return facade;
6. }

Response类
[java]
1. public HttpServletResponse getResponse() {
2. if (facade == null) {
3. facade = new ResponseFacade(this);
4. }
5. return (facade);
6. }


  可以看到它们返回都是各自的一个门面类,那么这样做有什么好处呢?
  Request对象中的很多方法都是内部组件之间相互交互时使用的,比如setComet、setRequestedSessionId等方法(这里就不一一列举了)。这些方法并不对外部公开,但是又必须设置为public,因为还需要跟内部组件之间交互使用。最好的解决方法就是通过使用一个Facade类,将与内部组件之间交互使用的方法屏蔽掉,只提供给外部程序感兴趣的方法。
  如果不使用Facade类,直接传递的是Request对象和Response对象,那么熟悉容器内部运作的程序员可以分别把ServletRequest和ServletResponse对象向下转换为Request和Response,并调用它们的公共方法。比如拥有Request对象,就可以调用setComet、setRequestedSessionId等方法,这会危害安全性。

作者:m13666368773