jsp文件是session創建的一個源頭,這里指的不是在jsp文件中用代碼或者標簽來操作session,這些都是在控制中的。容易忽視或者說根本就不會意識到的(比如我,就是寫jsp三年后才發現的)是,jsp有自動創建session的機制,在jsp頁面中,如果沒有明確的給出 <% @page session="false"%>,jsp頁面會非常乖巧(如果剛好需要)或者說是偷偷摸摸(如果不需要)的自動在生成的java文件中增加一句: javax.servlet.http.HttpSession session = request.getSession(true)。
為了驗證這個說法,我們做以下測試,先來一個最簡單的jsp文件,名字也簡單a.jsp,放到resin下。a.jsp的內容如下,注意里面有一個<%=1%>,后面會詳細解釋為什么需要這句話:
<%@ page session="true"%>
<html>
<head>
<title>test</title>
</head>
<body>
<%=1%>
</body>
</html>
用頁面訪問一下,然后到resin下webapp目錄的WEB-INF/work/_jsp目錄下找到_a__jsp.java,打開可以看到
public class _a__jsp extends com.caucho.jsp.JavaPage
有關jsp頁面是如何轉換為java文件再被編譯成class的介紹,請google。看我們關心的public void _jspService()方法:
public void _jspService(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException
{
javax.servlet.http.HttpSession session = request.getSession(true);
com.caucho.server.webapp.Application _jsp_application = _caucho_getApplication();
可以看到第一行,明確的調用了request.getSession(true),session就是再這里被自動創建的,這里也就是JSP中隱含的session對象的來歷。
使用抓包軟件,可以看到請求這個jsp頁面的http response里面有以下內容:
Set-Cookie: JSESSIONID=abc0zn72YuHtacvaaORBr; path=/
這個是剛才創建的session的jsessionid,被保存到cookie中。
然后繼續測試,設置為
<%@ page session="false"%>
打開java文件:
public void _jspService(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException
{
com.caucho.server.webapp.Application _jsp_application = _caucho_getApplication();
沒有javax.servlet.http.HttpSession session = request.getSession(true);
這行代碼了,同時http response 中沒有Set-Cookie: JSESSIONID=***的語句了。
ok,這下清晰了。
再來解釋一下為什么要在剛才的jsp文件里面增加<%=1%>這行,我們先做測試,將<%=1%>刪除,同樣測試<%@ page session="true/false"%>兩種情況。可以看到
public void _jspService(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException
{
javax.servlet.http.HttpSession session = request.getSession(true);
則不管是否有<%@ page session="true"%>都不自動創建session。考慮刪除<%=1%>后的jsp文件內容
<%@ page session="true"%>
<html>
<head>
<title>test</title>
</head>
<body>
</body>
</html>
這個是最簡單的純html頁面,估計是resin的實現考慮優化了這點。(resin: 都純html了,還要session干嘛?)
最后再澄清一點,發現網絡上很多人持有一個觀點: session在第一次訪問時創建。這個明顯的是被jsp文件自動創建(默認是true哦)session給誤導了,其實只有明確的調用request.getSession()/request.getSession(true)才會生成session。只是大多數人的jsp頁面不會明確加入<%@ page session="false"%>,也不了解這個機制,造成了錯誤的理解。