1. 程式人生 > >[01] JSP的基本認識

[01] JSP的基本認識

意思 system server image final doget 技術分享 nds ets

1、什麽是JSP

JSP,全稱JavaServer Pages,是由Sun Microsystems公司倡導和許多公司參與共同建立的一種使軟件開發者可以響應客戶端請求,而動態生成HTML、XML或其他格式文檔的Web網頁的技術標準。
什麽意思?
在 [01] Servlet是什麽 的文尾我曾經提到過,早期的網頁都是靜態的,也就是最普通的html形式,網頁內容寫了啥,就只能顯示啥,為了能根據不同的情況生成不同內容的動態網頁(比如不同用戶的賬戶管理頁面總不能都一樣吧),由Servlet接下了重任,通過數不清的out.println()來輸出html標簽和內容,就像下面這樣寫代碼:
  1. public class
    MyServlet extends HttpServlet {
  2. @Override
  3. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4. response.setContentType("text/html;charset=utf-8");
  5. PrintWriter out = response.getWriter();
  6. out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"
    );
  7. out.println("<HTML>");
  8. out.println(" <HEAD><TITLE>This is my Servlet</TITLE></HEAD>");
  9. out.println(" <BODY>");
  10. out.print(" This is ");
  11. out.print(this.getClass());
  12. out.println(", using the GET method");
  13. out.println
    (" </BODY>");
  14. for (int i = 0; i < 10; i++) {
  15. out.println("<font color=‘red‘>i=" + i + "</font><br>");
  16. }
  17. out.println("</HTML>");
  18. out.flush();
  19. out.close();
  20. }
  21. @Override
  22. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  23. doGet(request, response);
  24. }
  25. }

顯然太冗雜了,後來JSP出現,Servlet就卸任專心去做控制器了。那麽JSP是什麽呢?JSP在表面上看來就是 "HTML+Java代碼" 的組合,其中HTML實現靜態部分,Java代碼實現動態部分。主要表現在於普通的html代碼中,以<% %>形式來標記Java代碼。
比如我想要生成一個1-3的多選框,我可以這些寫我的JSP頁面:
  1. <%@page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head><title>Simple jsp page</title></head>
  4. <body>
  5. <%
  6. for (int i = 1; i < 4; i++) {
  7. %>
  8. <input type="checkbox"> <%=i%> <br>
  9. <%
  10. }
  11. %>
  12. </body>
  13. </html>


而得到的效果如下圖,這顯然比你傻乎乎地寫靜態html好多了,因為這裏的i是可變的,你也可以通過Java代碼獲取其他的數據進行展示。技術分享圖片 在上述的代碼中,我們可以看到,JSP中Java代碼最基本的表達有兩種方式:
<% Java代碼 %>腳本元素
<%= 輸出表達式 %>輸出表達式

2、JSP的本質和基本運行過程

為什麽JSP可以做到執行Java代碼呢?原因很簡單,JSP在技術上來說,最終它的本質就是一個Servlet,你說它能不能執行Java代碼?
那麽它實際是由容器執行的(比如Tomcat),大致流程是這樣:
  • 翻譯:將JSP文件翻譯成Java文件(存放在tomcat目錄下的 /work/Catalina/localhost/)
  • 編譯:將Java文件便宜成class文件
  • 實例化:由Tomcat創建JSP類的對象
  • 提供服務:由Tomcat調用JSP對象的_jspService方法,生成響應,返回給瀏覽器進行顯示

我們試著寫了兩個JSP頁面,一個是上述例中生成1-3多選框的代碼,一個是空的JSP,並啟動了tomcat,然後可以看到tomcat生成了如下文件:技術分享圖片 我們先看空的JSP生成的java類中,即上圖中testEmpty_jsp.java的_jspService()方法:
  1. public void _jspService(HttpServletRequest request, HttpServletResponse response)
  2. throws java.io.IOException, ServletException {
  3. PageContext pageContext = null;
  4. HttpSession session = null;
  5. ServletContext application = null;
  6. ServletConfig config = null;
  7. JspWriter out = null;
  8. Object page = this;
  9. JspWriter _jspx_out = null;
  10. PageContext _jspx_page_context = null;

  11. try {
  12. response.setContentType("text/html");
  13. pageContext = _jspxFactory.getPageContext(this, request, response,
  14. null, true, 8192, true);
  15. _jspx_page_context = pageContext;
  16. application = pageContext.getServletContext();
  17. config = pageContext.getServletConfig();
  18. session = pageContext.getSession();
  19. out = pageContext.getOut();
  20. _jspx_out = out;
  21. } catch (Throwable t) {
  22. if (!(t instanceof SkipPageException)) {
  23. out = _jspx_out;
  24. if (out != null && out.getBufferSize() != 0)
  25. try {
  26. out.clearBuffer();
  27. } catch (java.io.IOException e) {
  28. }
  29. if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
  30. }
  31. } finally {
  32. _jspxFactory.releasePageContext(_jspx_page_context);
  33. }
  34. }

可見,即便是空的JSP文件,也會翻譯出java類,而且該類中已經有一些代碼,且是“固定”的,也就是說,任何的JSP文件,最終翻譯生成的類中,都有這些代碼。
那麽我們再看另一個寫了內容的JSP文件,也就是我們舉例用過的JSP,如下:
  1. <%@page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head><title>Simple jsp page</title></head>
  4. <body>
  5. <%
  6. for (int i = 1; i < 4; i++) {
  7. %>
  8. <input type="checkbox"> <%=i%> <br>
  9. <%
  10. }
  11. %>
  12. </body>
  13. </html>

它的java類中的_jspService()是這樣的:
  1. public void _jspService(HttpServletRequest request, HttpServletResponse response)
  2. throws java.io.IOException, ServletException {
  3. PageContext pageContext = null;
  4. HttpSession session = null;
  5. ServletContext application = null;
  6. ServletConfig config = null;
  7. JspWriter out = null;
  8. Object page = this;
  9. JspWriter _jspx_out = null;
  10. PageContext _jspx_page_context = null;

  11. try {
  12. response.setContentType("text/html;charset=UTF-8");
  13. pageContext = _jspxFactory.getPageContext(this, request, response,
  14. null, true, 8192, true);
  15. _jspx_page_context = pageContext;
  16. application = pageContext.getServletContext();
  17. config = pageContext.getServletConfig();
  18. session = pageContext.getSession();
  19. out = pageContext.getOut();
  20. _jspx_out = out;
  21. out.write("\r\n");
  22. out.write("<html>\r\n");
  23. out.write("<head><title>Simple jsp page</title></head>\r\n");
  24. out.write("<body>\r\n");
  25. for (int i = 1; i < 4; i++) {
  26. out.write("\r\n");
  27. out.write(" <input type=\"checkbox\"> ");
  28. out.print(i);
  29. out.write(" <br>\r\n");
  30. }
  31. out.write("\r\n");
  32. out.write("</body>\r\n");
  33. out.write("</html>");
  34. } catch (Throwable t) {
  35. if (!(t instanceof SkipPageException)) {
  36. out = _jspx_out;
  37. if (out != null && out.getBufferSize() != 0)
  38. try {
  39. out.clearBuffer();
  40. } catch (java.io.IOException e) {
  41. }
  42. if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
  43. }
  44. } finally {
  45. _jspxFactory.releasePageContext(_jspx_page_context);
  46. }
  47. }

可以看到,JSP中的內容怎麽來的?就是這裏來的,這些代碼插入到那些“固定代碼”之後進行輸出,包括了HTML和Java代碼的執行。
所以,由此可以看出,JSP文件的究竟是怎麽回事
  • JSP文件本質是一個Java類,這個類遵守Servlet的規範,所以也可以說JSP就是一個Servlet
  • JSP文件對應的Java類由容器翻譯生成
  • JSP文件中的所有內容,會翻譯到Java類中_jspService方法中,並放到"固定"代碼之後
  • 我們寫的JSP代碼,無非就是Java類_jspService方法中方法體的一部分


[01] JSP的基本認識