request.include和request.foward後是否共享Request和Response的問題
阿新 • • 發佈:2018-12-18
這兩天在細看<深入體驗Java_Web開發內幕-核心基礎>一書,書比較老了,使用的tomcat和servlet版本差距都比較大。書中提及在foward轉發過程中,request物件和response物件一直都是同一個。但我總覺得有些問題,做了以下測試:
@WebServlet("/Test") public class ForwardingServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("訪問req:"+req.hashCode()); System.out.println("訪問resp:"+resp.hashCode()); req.setAttribute("req",req); req.setAttribute("resp",resp); req.getRequestDispatcher("Input").include(req,resp); } }
@WebServlet("/Input") public class ForwardedServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("轉到req:"+req.hashCode()); System.out.println("轉到resp:"+resp.hashCode()); if(req.getAttribute("req")==req)System.out.println("req:"+true); else System.out.println("req:"+false); if(req.getAttribute("resp")==resp)System.out.println("resp:"+true); else System.out.println("resp:"+false); } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% System.out.println("Jspreq:"+request.hashCode()); System.out.println("JSPresp:"+response.hashCode()); if(request.getAttribute("req")==request)System.out.println("req:"+true); else System.out.println("req:"+false); if(request.getAttribute("resp")==response)System.out.println("resp:"+true); else System.out.println("resp:"+false); %> </body> </html>
FowardingServlet分別轉向jsp和servlet的輸出結果如下:
從結果可以發現,foward方法resp的物件是同一個,req的物件不是同一個,include方法四個物件都不一樣。
因此,關於預設servlet的一些疑點就可以解釋清楚了,一個response物件只能使用位元組流或者字元流中的一個,當訪問一個靜態HTML檔案,圖片等資源時,是通過預設servlet去訪問的,因此如果在訪問servlet裡面轉到一個圖片,又呼叫了getWriter輸出了資料,則會報錯,這是因為它們共享一個servlet,而且讀取圖片只能用位元組流。