最近刚好学SpringMVC,之前javaweb学的不扎实这里又磕磕绊绊碰到好多小问题,自己记录一下。
问题就是转发的时候request在服务器内部是同一个对象吗?按照我之前的理解,转发是服务器内部行为,那么应该是一个对象:
而且写的时候不也是request.getRequestDispatcher(“xxx”).forward(request, response)嘛,这不就把这个request就传进去了,所以我一直认为是同一个对象。但是自己动手实践了一下,在控制台打印一下发现并不是这样,代码如下:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="a.jsp">前往a.jsp</a>
</body>
</html>
a.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>a.jsp</title>
</head>
<body>
<%
System.out.println(request.toString());
request.getRequestDispatcher("b.jsp").forward(request, response);
%>
</body>
</html>
b.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>b.jsp</title>
</head>
<body>
<%
System.out.println(request.toString());
%>
</body>
</html>
控制台输出:
org.apache.catalina.connector.RequestFacade@6e6a160b
org.apache.catalina.core.ApplicationHttpRequest@2b572a89
也就是说在服务器内部肯定不是用浏览器发来的那个request跳转的,这么一想也很有道理,因为浏览器发来的request是无法直接访问WEB-INF目录下的内容的,但是转发行为是可以转发给WEB-INF目录下的页面的,如果对这个request不做任何处理就可以做到这件事,那为什么浏览器的request不能直接访问WEB-INF呢?所以我猜测tomcat内部是对这个request做了一些处理或者包装,才可以访问WEB-INF目录的,所以导致了控制台输出不一样。
先看一下tomcat对于HttpServletRequest的继承结构:
可以看到它对这个接口实现了很多类,应该是不同的类有不同的权限和使用场景的。
其中的Request是tomcat对最底层的http请求进行包装的,而刚刚在控制台看到的输出是RequestFacade对象,再点进去看一下发现它是对Request的进一步包装:
而当它调用getRequestDispatcher()的时候,代码是这样的:
会有一个GetRequestDispatcherPrivilegedAction,内部的方法是native的就没有再深入看下去了,看类名和注释大概是可以有更高优先级的行为,应该是这里创建了ApplicationHttpRequest对象在服务器内部跳转的。
以上只是很粗略地看了一下源码,不一定正确,tomcat具体怎么运作的还要等以后学有余力再深入研究。