1、JSP的由来 在JSP出现之前,为了实现动态网页的效果,服务器端利用 Servlet 的输出流向客户端发送HTML标签以及HTML页面中的内容,但是在多数动态网页中,绝大部分内容是静态的,只有少量内容需要动态实现。但是为了这少量的动态内容,程序猿依然要用Servlet 输出其中所有的静态内容,这就使得整个Servlet 程序代码非常臃肿,导致Servlet 的开发效率非常低下。 为了弥补Servlet 的缺陷,SUN公司在Servlet 的基础上推出了JSP(Java Server Pages)技术作为解决方案。JSP是简化Servlet 编写的一种技术,它由态部分和动态部分两部分组成,静态部分用于写入标准的HTML标签及内容;动态部分就是嵌入的Java代码与JSP动态标签了。通过这种方式,使静态的部分直接使用HTML代码编写,对于动态的内容则使用 JAVA 脚本编写。 对于Servlet 来说,无论动态、静态都用Java代码编写;而JSP则将静态的分出来,全部用HTML写(底层还是使用Java包装);动态的用Java 写。究其本质还是一样的,所以说,JSP的本质就是一种特殊的Servlet 。 2、JSP的语法 JSP = HTML + Java 脚本 + JSP 标签(指令),JSP中三种Java 脚本: ● <%...%>:Java代码片段,用于定义0~N条Java 语句,方法中能够写什么,这里面就能放什么; ● <%= %>:Java 表达式,用于输出一条表达式或变量的结果。 response.getWriter().print() 方法中能够写什么,这里面就能够写什么; ● <%! … %> :声明,用来创建类的成员变量和成员方法,Java 类中能够写什么,这里面就能够写什么,要注意的是,里面的内容不在 _jspService() 方法之内,直接被JSP转化后的类体包含。 3、JSP 原理 前面已经阐述过,JSP的本质实质是一种特殊形式的 Servlet : ● 当用户访问一个JSP页面时,会向 Servlet 容器(这里是Tomcat)发出请求; ● 如果这个JSP页面是第一次被访问或者这个页面被改动过时,服务器会把JSP 编译成 .java文件,当然,这个.java 就是一个servlet类,然后再把 .java 文件编译成.class 文件。因为编译会耗费一定时间,所以页面在第一次被访问或改动后被访问时会花费较长的访问时间; ● 创建该类对象,最后由Servlet 容器调用它的service() 方法; ● 第二次请求同一JSP时,直接调用service() 方法。 4、验证JSP原理 首先,我们来写一个hello.jsp文件: [java] view plaincopyprint? 1. 2. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 3. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4. 5. <% 6. String s = request.getHeader("User-Agent"); 7. %> 8. 9. 10. 11. 12. My JSP 'a.jsp' starting page 13. 14. 15. 16. 17. 18. 19. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. <% 33. for(int i = 0; i < 10; i++) { 34. %> 35. 36. 37. 38. 39. 40. <% }%> 41.
姓名年龄性别
张三18
42. 43. 44. 45. <%! 46. public void fun1() { 47. System.out.println("hello"); 48. } 49. 50. %> 51. <%int a = 10; %> 52. 53. <%a++; %> 54. 55. <%=a %> 56. 57. 58. 59. 60.
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String s = request.getHeader("User-Agent"); %> My JSP 'a.jsp' starting page <% for(int i = 0; i < 10; i++) { %> <% }%>
姓名 年龄 性别
张三 18
<%! public void fun1() { System.out.println("hello"); } %> <%int a = 10; %> <%a++; %> <%=a %>
然后让我们在tomcat 下找到被编译成的.java 文件,为了节省空间,我把一些解释标记在代码注释中: [java] view plaincopyprint? 1. 2. /* 3. * Generated by the Jasper component of Apache Tomcat 4. * Version: Apache Tomcat/7.0.42 5. * Generated at: 2015-12-27 10:03:19 UTC 6. * Note: The last modified time of this file was set to 7. * the last modified time of the source file after 8. * generation to assist with modification tracking. 9. */ 10. package org.apache.jsp; 11. 12. import javax.servlet.*; 13. import javax.servlet.http.*; 14. import javax.servlet.jsp.*; 15. import java.util.*; 16. 17. public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase 18. implements org.apache.jasper.runtime.JspSourceDependent { 19. 20. 21. public void fun1() { //要特别注意,这是在<%! %>中定义的方法,没有被放在service方法中 22. System.out.println("hello"); 23. } 24. 25. 26. private static final javax.servlet.jsp.JspFactory _jspxFactory = 27. javax.servlet.jsp.JspFactory.getDefaultFactory(); 28. 29. private static java.util.Map _jspx_dependants; 30. 31. private javax.el.ExpressionFactory _el_expressionfactory; 32. private org.apache.tomcat.InstanceManager _jsp_instancemanager; 33. 34. public java.util.Map getDependants() { 35. return _jspx_dependants; 36. } 37. 38. public void _jspInit() { 39. _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); 40. _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); 41. } 42. 43. public void _jspDestroy() { 44. } 45. 46. public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) 47. throws java.io.IOException, javax.servlet.ServletException { //这是_jspService()方法 48. 49. final javax.servlet.jsp.PageContext pageContext; //内置对象的初始化 50. javax.servlet.http.HttpSession session = null; 51. final javax.servlet.ServletContext application; 52. final javax.servlet.ServletConfig config; 53. javax.servlet.jsp.JspWriter out = null; 54. final java.lang.Object page = this; 55. javax.servlet.jsp.JspWriter _jspx_out = null; 56. javax.servlet.jsp.PageContext _jspx_page_context = null; 57. 58. 59. try { 60. response.setContentType("text/html;charset=UTF-8"); 61. pageContext = _jspxFactory.getPageContext(this, request, response, 62. null, true, 8192, true); 63. _jspx_page_context = pageContext; 64. application = pageContext.getServletContext(); 65. config = pageContext.getServletConfig(); 66. session = pageContext.getSession(); 67. out = pageContext.getOut(); 68. _jspx_out = out; 69. 70. out.write("\r\n"); 71. out.write("\r\n"); 72. out.write("\r\n"); 73. 74. String s = request.getHeader("User-Agent"); //它的原身是String s = request.getHeader("User-Agent");,被直接拿过来了 75. 76. 77. out.write("\r\n"); 78. out.write("\r\n"); 79. out.write("\r\n"); 80. out.write("\r\n"); //这些都是HTML代码,底层被包装成和Servlet 一样的实现方式 81. out.write(" \r\n"); 82. out.write(" My JSP 'a.jsp' starting page\r\n"); 83. out.write(" \r\n"); 84. out.write("\t\r\n"); 85. out.write("\t\r\n"); 86. out.write("\t \r\n"); 87. out.write("\t\r\n"); 88. out.write("\t\r\n"); 89. out.write("\t\r\n"); 92. out.write("\r\n"); 93. out.write(" \r\n"); 94. out.write(" \r\n"); 95. out.write(" \r\n"); 96. out.write(" \r\n"); 97. out.write("\t\r\n"); 98. out.write("\t \r\n"); 99. out.write("\t \r\n"); 100. out.write("\t \r\n"); 101. out.write("\t\r\n"); 102. 103. for(int i = 0; i < 10; i++) { //这也是直接拿过来的 104. 105. out.write("\t\r\n"); 106. out.write("\t\r\n"); 107. out.write("\t \r\n"); 108. out.write("\t \r\n"); 109. out.write("\t \r\n"); 110. out.write("\t\r\n"); 111. } 112. out.write("\r\n"); 113. out.write("
姓名年龄性别
张三18
\r\n"); 114. out.write("\r\n"); 115. out.write("\r\n"); 116. out.write("\r\n"); 117. out.write('\r'); 118. out.write('\n'); 119. int a = 10; //这些是定义的变量,可以看到是放在了service方法中的 120. out.write("\r\n"); 121. out.write("\r\n"); 122. a++; 123. out.write("\r\n"); 124. out.write("\r\n"); 125. out.print(a ); 126. out.write("\r\n"); 127. out.write("\r\n"); 128. out.write(" \r\n"); 129. out.write("\r\n"); 130. } catch (java.lang.Throwable t) { 131. if (!(t instanceof javax.servlet.jsp.SkipPageException)){ 132. out = _jspx_out; 133. if (out != null && out.getBufferSize() != 0) 134. try { out.clearBuffer(); } catch (java.io.IOException e) {} 135. if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); 136. else throw new ServletException(t); 137. } 138. } finally { 139. _jspxFactory.releasePageContext(_jspx_page_context); 140. } 141. } 142. } 143. 144.
/* * Generated by the Jasper component of Apache Tomcat * Version: Apache Tomcat/7.0.42 * Generated at: 2015-12-27 10:03:19 UTC * Note: The last modified time of this file was set to * the last modified time of the source file after * generation to assist with modification tracking. */ package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import java.util.*; public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { public void fun1() { //要特别注意,这是在<%! %>中定义的方法,没有被放在service方法中 System.out.println("hello"); } private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } public void _jspDestroy() { } public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { //这是_jspService()方法 final javax.servlet.jsp.PageContext pageContext; //内置对象的初始化 javax.servlet.http.HttpSession session = null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null; javax.servlet.jsp.PageContext _jspx_page_context = null; try { response.setContentType("text/html;charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("\r\n"); out.write("\r\n"); out.write("\r\n"); String s = request.getHeader("User-Agent"); //它的原身是String s = request.getHeader("User-Agent");,被直接拿过来了 out.write("\r\n"); out.write("\r\n"); out.write("\r\n"); out.write("\r\n"); //这些都是HTML代码,底层被包装成和Servlet 一样的实现方式 out.write(" \r\n"); out.write(" My JSP 'a.jsp' starting page\r\n"); out.write(" \r\n"); out.write("\t\r\n"); out.write("\t\r\n"); out.write("\t \r\n"); out.write("\t\r\n"); out.write("\t\r\n"); out.write("\t\r\n"); out.write("\r\n"); out.write(" \r\n"); out.write(" \r\n"); out.write(" \r\n"); out.write(" \r\n"); out.write("\t\r\n"); out.write("\t \r\n"); out.write("\t \r\n"); out.write("\t \r\n"); out.write("\t\r\n"); for(int i = 0; i < 10;
姓名年龄性别