2.2 JSP的基本原理




JSP的本质是Servlet,当用户向指定Servlet发送请求时,Servlet利用输出流动态生成HTML页面,包括每一个静态的HTML标签和所有在HTML页面中出现的内容。

由于包括大量的HTML标签、大量的静态文本及格式等,导致Servlet的开发效率极为低下。所有的表现逻辑,包括布局、色彩及图像等,都必须耦合在Java代码中,这的确让人不胜其烦。JSP的出现弥补了这种不足,JSP通过在标准的HTML页面中嵌入Java代码,其静态的部分无须Java程序控制,只有那些需要从数据库读取或需要动态生成的页面内容,才使用Java脚本控制。

从上面的介绍可以看出,JSP页面的内容由如下两部分组成。

静态部分:标准的HTML标签、静态的页面内容,这些内容与静态HTML页面相同。

动态部分:受Java程序控制的内容,这些内容由Java程序来动态生成。

下面是一个最简单的JSP页面代码。

程序清单:codes\02\2.2\jspPrinciple\first.jsp

 
 
  1. <%@ page contentType="text/html; charset=GBK"  language="java" errorPage="" %> 
  2. <html> 
  3. <head> 
  4. <title>欢迎</title> 
  5. </head> 
  6. <body> 

欢迎学习Java Web知识,现在时间是:

 
 
  1. <%out.println(new java.util.Date());%> 
  2. </body> 
  3. </html> 

上面的页面中粗体字代码放在<%和%>之间,表明这些是Java脚本,而不是静态内容,通过这种方式就可以把Java代码嵌入HTML页面中,这就变成了动态的JSP页面。在浏览器中浏览该页面,将看到如图2.2所示的页面。

 
图2.2  JSP页面的静态部分和动态部分

上面JSP页面必须放在Web应用中才有效,所以编写该JSP页面之前应该先构建一个Web应用。本章后面介绍的内容都必须运行在Web应用中,所以也必须先构建Web应用。

从表面上看,JSP页面已经不再需要Java类,似乎完全脱离了Java面向对象的特征。事实上,JSP的本质依然是Servlet(一个特殊的Java类),每个JSP页面就是一个Servlet实例--JSP页面由系统编译成Servlet,Servlet再负责响应用户请求。也就是说,JSP其实也是Servlet的一种简化,使用JSP时,其实还是使用Servlet,因为Web应用中的每个JSP页面都会由Servlet容器生成对应的Servlet。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。

再看如下一个简单的JSP页面。

程序清单:codes\02\2.2\jspPrinciple\test.jsp

 
 
  1. <!-- 表明这是一个JSP页面 --> 
  2. <%@ page contentType="text/html; charset=GBK"  language="java" errorPage="" %> 
  3. <html xmlns="http://www.w3.org/1999/xhtml"> 
  4. <head> 
  5.     <title> 第二个JSP页面 </title> 
  6. </head> 
  7. <body> 
  8. <!-- 下面是Java脚本 --> 
  9. <%for(int i = 0 ; i < 7; i++)  
  10. {  
  11. out.println("<font size='" + i + "'>");  
  12. %> 
  13. 疯狂Java训练营(Wild Java Camp)</font> 
  14. <br/> 
  15. <%}%> 
  16. </body> 
  17. </html> 

当启动Tomcat之后,可以在Tomcat的work\Catalina\localhost\jspPrinciple\org\apache\jsp目录下找到如下文件(本Web应用名为jspPrinciple,上面JSP页的名为test.jsp):test_jsp.java和test_jsp.class。这两个文件都是由Tomcat生成的,Tomcat根据JSP页面生成对应Servlet的Java文件和class文件。

下面是test1_jsp.java文件的源代码,这是一个特殊的Java类,是一个Servlet类。

程序清单:codes\02\2.2\test.java

 
 
  1. //JSP页面经过Tomcat编译后默认的包  
  2. package org.apache.jsp;  
  3. import javax.servlet.*;  
  4. import javax.servlet.http.*;  
  5. import javax.servlet.jsp.*;  
  6. //继承HttpJspBase类,该类其实是Servlet的子类  
  7. public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase  
  8.     implements org.apache.jasper.runtime.JspSourceDependent {  
  9.     private static final JspFactory _jspxFactory =  JspFactory.getDefaultFactory();  
  10.     private static java.util.List<String> _jspx_dependants;  
  11.     private javax.el.ExpressionFactory _el_expressionfactory;  
  12.     private org.apache.tomcat.InstanceManager _jsp_instancemanager;  
  13.     public java.util.List<String> getDependants() {  
  14.         return _jspx_dependants;  
  15.     }  
  16.     public void _jspInit() {  
  17.         _el_expressionfactory = _jspxFactory.getJspApplicationContext  
  18.             (getServletConfig().getServletContext()).getExpressionFactory();  
  19.         _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory  
  20.             .getInstanceManager(getServletConfig());  
  21.     }  
  22.     public void _jspDestroy() {  
  23.     }  
  24.     //用于响应用户请求的方法  
  25.     public void _jspService(HttpServletRequest request, HttpServletResponse response)  
  26.         throws java.io.IOException, ServletException {  
  27.         PageContext pageContext = null;  
  28.         HttpSession session = null;  
  29.         ServletContext application = null;  
  30.         ServletConfig config = null;  
  31.         JspWriter out = null;  
  32.         Object page = this;  
  33.         JspWriter _jspx_out = null;  
  34.         PageContext _jspx_page_context = null;  
  35.  
  36.         try {  
  37.             response.setContentType("text/html; charset=GBK");  
  38.             pageContext = _jspxFactory.getPageContext(this, request, response,  
  39.             "", true, 8192, true);  
  40.             _jspx_page_context = pageContext;  
  41.             application = pageContext.getServletContext();  
  42.             config = pageContext.getServletConfig();  
  43.             session = pageContext.getSession();  
  44.             out = pageContext.getOut();  
  45.             _jspx_out = out;  
  46.             out.write("\r\n");  
  47.             out.write("\r\n");  
  48.             out.write("\r\n");  
  49.             out.write("<!DOCTYPE html PUBLIC \"-// W3C//DTD XHTML 1.0 Transitional               //EN\"\r\n");  
  50.             out.write("\t\"http://www.w3.org/TR/ xhtml1/DTD/xhtml1-transitional. dtd\">          \r\n");  
  51.             out.write("<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n");  
  52.             out.write("<head>\r\n");  
  53.             out.write("\t<title> 第二个JSP页面 </title>\r\n");  
  54.             out.write("\t<meta name=\"website\" content=\http://www.crazyit.org\ />\                r\n");  
  55.             out.write("</head>\r\n");  
  56.             out.write("<body>\r\n");  
  57.             out.write("<!-- 下面是Java脚本 -->\r\n");  
  58.             for(int i = 0 ; i < 7; i++)  
  59.             {  
  60.             out.println("<font size='" + i + "'>");  
  61.             out.write("\r\n");  
  62.             out.write("疯狂Java训练营(Wild Java Camp)</font>\r\n");  
  63.             out.write("<br/>\r\n");  
  64.             }  
  65.             out.write("\r\n");  
  66.             out.write("</body>\r\n");  
  67.             out.write("</html>");  
  68.         } catch (Throwable t) {  
  69.             if (!(t instanceof SkipPageException)){  
  70.                 out = _jspx_out;  
  71.                 if (out != null && out.getBufferSize() != 0)  
  72.                 try { out.clearBuffer(); } catch (java.io.IOException e) {}  
  73.                 if (_jspx_page_context != null) _jspx_page_context.handlePage                   Exception(t);  
  74.             }  
  75.         } finally {  
  76.             _jspxFactory.releasePageContext(_jspx_page_context);  
  77.         }  
  78.     }  
  79. }  

初学者看到上面的Java类可能有点难以阅读,其实这就是一个Servlet类的源代码,该Java类主要包含如下三个方法(去除方法名中的_jsp前缀,再将首字母小写)。

init():初始化JSP/Servlet的方法。

destroy():销毁JSP/Servlet之前的方法。

service():对用户请求生成响应的方法。

即使读者暂时不了解上面提供的Java代码,也依然不会影响JSP页面的编写,因为这都是由Web容器负责生成的,后面介绍了编写Servlet的知识之后再来看这个Java类将十分清晰。浏览该页面可看到如图2.3所示的页面。

 
图2.3  使用Java代码控制静态内容

从图2.3中可以看出,JSP页面里的Java代码不仅仅可以输出动态内容,还可以动态控制页面里的静态内容,例如,从图2.3中看到将"疯狂Java训练营(Wild Java Camp)"重复输出了7次。

根据图2.3所示的执行效果,再次对比test1.jsp和test1_jsp.java文件,可得到一个结论:JSP页面中的所有内容都由test1_jsp.java文件的页面输出流来生成。图2.4显示了JSP页面的工作原理。

 
图2.4  JSP页面的工作原理

根据上面的JSP页面工作原理图,可以得到如下4个结论:

JSP文件必须在JSP服务器内运行。

JSP文件必须生成Servlet才能执行。

每个JSP页面的第一个访问者速度很慢,因为必须等待JSP编译成Servlet。

JSP页面的访问者无须安装任何客户端,甚至不需要可以运行Java的运行环境,因为JSP页面输送到客户端的是标准HTML页面。

JSP技术的出现,大大提高了Java动态网站的开发效率,所以得到了Java动态网站开发者的广泛支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值