ITEEDU

JSP/Servlet: 第一个JSP程序

首先请确定您已经了解了什么是Servlet容器,并已设定好Web应用程序相关目录与web.xml,然后启动您的服务器。

假设您的Web应用程序是在myjsp目录下,直接在该目录下开始撰写您的第一个Hello!First JSP!程序,JSP程序的扩展名是*.jsp,假设您的程序档案命名为hello.jsp,其内容如下:

hello.jsp

<html>
<head><title>Hello!First JSP!</title></head>
<body>
 <b><% out.println("Hello!First JSP!"); %></b>
</body>
</html> 

在这个JSP网页中,您主要撰写HTML的标签,就如同一般编辑HTML网页一样,这是JSP网页的静态部份,这部份输出至浏览器的结果就如您所撰写的内容;<% 与 %>之间的程序代码是JSP的Quoting,您可以在Quoting之间撰写有关于网页动态的部份,撰写的方式可以使用Java语法,但这种写法是针对熟悉Java的程序设计人员而设计的。

如果是网页设计人员的话,或许这么撰写会比较习惯一点:

hello.jsp

<html>
<head><title>Hello!First JSP!</title></head>
<body>
  <b><%="Hello!First JSP!"%></b>
</body>
</html> 
<%= expression%>是表达式标签,可以直接将表达式的结果转换为文字传回至浏览器,这样的写法比较近似于网页设计人员所熟悉的卷标语法。上面两个JSP网页可以让您测试Web应用程序的基本环境设定是否正确,没有意外的话,在浏览器中键入:

http://localhost:8080/myjsp/hello.jsp
Servlet容器就会开始将JSP网页转译为Servlet原始码、编译、加载并执行程序,最后将结果传回给浏览器,结果只是在浏览器中显示 Hello! World!,而传回的HTML内容如下:

<html>
<head>
  <title>Hello!First JSP!</title></head>
<body> 
  <b>Hello!First JSP!</b>
</body> 
</html> 

上面的例子是将Java的字符串对象"Hello! First JSP!"转换为文字并传回至浏览器,两个例子都没有展现动态的输出,为了展现动态程序的效果,来看下面这个例子:

hello.jsp

<html>
<head>
   <title>Hello!First JSP!</title></head>
<body> 
   Hello,it's <b><%= new java.util.Date() %> .
</body>
</html> 

这写法是使用Java语法的写法,简单的说生成一个 对象,该对象包括时间信息,转换为字符串并传回,这个JSP网页会将目前服务器上的时间传回至浏览器上,每次都会传回不同的结果,例如结果是:

<html>
<head>
  <title>Hello!First JSP!</title></head>
<body> 
 Hello,it's <b>Mon Jan 24 18:07:31 GMT+08:00 2005 .
</body> 
</html> 
JSP网页会由容器转换为Servlet原始码,经由编译器编译,然后加载至JVM中,最后执行并传回执行的结果,在第一个例子中,out.println()表示由一个JSPWriter对象的println ()方法,将指定的文字传回至浏览器,这个部份是包括在<% 与 %>之间,是JSP网页的动态部份,事实上,区分动态与静态两个部份只是在区分HTML卷标与JSP语法部份方便而已,对于JSP网页转换过后的 Servlet程序,所有的结果都是Servlet程序运算的结果,即使它是在JSP网页中是纯綷的HTML标签,举个例子,Hello! First JSP!的JSP网页,转换为Servlet网页之后,其中输出的部份是:

package   org.apache.jsp; 
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class helloworld_jsp
extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws java.io.IOException, ServletException {
......
out.write("<html>\n");
out.write("<head><title>Hello!First JSP!</title></head>\n");
out.write("<body>\n");
out.write("??? <b>");
out.print("Hello! First JSP!");
out.write("\n");
out.write("</body>\n");
out.write("</html>\n");
}
}

如果您有兴趣,可以看看完整产生的Servlet原始码,假设您JSP的所在目录是 webapps/myjsp/helloworld.jsp,以我的Tomcat5.5.4来说,产生的Servlet原始码是在 work/Catalina/localhost/myjsp下,由于package是org.apache.jsp,所以您可以在 work/Catalina/localhost/myjsp/org/apache/jsp/下找到对应的原始码 helloworld_jsp.java,编译好的Servlet类别档也在其下。

所以转换过后,JSP网页的静态HTML部份,在Servlet中也是一个Java程序运算输出的结果,基本上,一个JSP网页会转换为一个Servlet类别,一个JSP网页中不同的元素,会对应至Servlet中的field、method等等目标。

JSP网页在第一次被读取时,会转换为Servlet并加载,之后若JSP网页没有变动,则容器就不会再为其进行转换,而是直接从内存中执行加载的 Servlet程序,所以JSP网页在第一次读取执行时会比较慢,因为必须先转换为Servlet原始码、编译后加载JVM执行,但之后再次请求同一个 JSP网页时,执行速度则相当于执行Servlet的速度;如果JSP网页被修改,则再次读取JSP网页时,容器发觉有被修改,就会重新转换为新的 Servlet程序、编译后重新加载。

依容器制造商的不同,您可以决定让JSP先进行转译与编译的动作,在JSP规格文件(JSP 11.4.2)中提过,您可以在查询时附加一个查询字符串(Query String):?jsp_precompile,如果容器制造商有实作的话,则会先对JSP进行转译与编译的动作。