jsp的執行原理
public class PageServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //設定響應編碼格式 resp.setContentType("text/html;charset=utf-8"); //響應處理結果 //獲取request作用域資料 String str = (String) req.getAttribute("str")==null?"":(String) req.getAttribute("str"); resp.getWriter().write("<html>"); resp.getWriter().write("<head>"); resp.getWriter().write("</head>"); resp.getWriter().write("<body>"); //當request物件中有str資訊時,將其顯示 沒有就是空字串 resp.getWriter().write("<font color='red' size='20px'>"+str+"</font>"); //通過get方式 提交到login的servlet resp.getWriter().write("<form action='login' method='get'>"); resp.getWriter().write("使用者名稱:<input type='text' name='uname' value=''/><br/>"); resp.getWriter().write("密碼:<input type='password' name='pwd' value=''/><br/>"); resp.getWriter().write("<input type='submit' value='登入'/><br/>"); resp.getWriter().write("</form>"); resp.getWriter().write("</body>"); resp.getWriter().write("</html>"); } }
所以有了jsp,可以讓我們直接寫前端的一些指令碼語言,而不用在servlet裡面用響應那樣寫。新建一個web專案,webroot下新建一個名為1.jsp的檔案,如下
當我們在瀏覽器直接訪問這個專案時http://localhost:8086/jsp/1.jsp (jsp是我的虛擬專案名),會列印body裡的東西。
但是我們要知道,伺服器只認識servlet,我們請求到時,伺服器會先去jsp專案下的web.xml找一個1.jsp的servlet,發現沒有。(伺服器認為1.jsp是一個servlet的別名).
沒有後,會再去tomcat下的conf下的web.xml中找1.jsp的一個servlet(tomcat下的web.xml中配置的是公共的),它找到這樣的配置,以.jsp結尾的url,通過這個它找到servlet-name為jsp,最後找到了JspServlet。
JspServlet的很重要的一個功能就是將一個.jsp檔案轉義為一個servlet檔案。比如專案下的1.jsp檔案,對應的是在這個目錄下apache-tomcat-7.0.86\work\Catalina\localhost\jsp\org\apache\jsp轉義後的名為_1_jsp.java的servlet檔案。其實伺服器執行的就是這個轉義後的檔案。
但是伺服器執行servlet會找到service去執行,轉義後的檔案是沒有service的,只有_jspService,我們會發現它繼承了extends org.apache.jasper.runtime.HttpJspBase,在該父類中我們可以看到它呼叫了_jspService
所以,我們伺服器執行的並不是我們專案下的1.jsp檔案,而是經過轉義後的_1_jsp.java檔案,從始至終伺服器都不認識1.jsp檔案。