集成开发环境的使用在给开发人员的开发工作带来极大便利的同时,也带来了一些“朦胧感”——它向用户屏蔽了一些具体的操作流程和细节,开发人员在感受开发工具带来的“智能”的同时也常常会有一种“傻瓜式”的感觉。本文试图“追本溯源”,讨论手工编译Servlet和JSP页面的方法与步骤,希望能够加深大家对相关技术的理解。
(1)说明
在本例中,使用的操作系统为CentOS 5.4,使用的Tomcat Servlet/JSP容器的版本为5.5.28,使用的JDK的版本为OpenJDK 1.6.0。另外,为了便于测试,假设存在如下目录:
/codolio:用于存放用于编译的Servlet源文件和JSP页面;
/codolio/dist:用于存放生成的目标文件,如Servlet class文件、由JSP转换来的Servlet源文件等;
/codolio/libs:用于存放编译过程中依赖的jar和class文件。
(2)编译Servlet
用户编写的Servlet本质上来说就是一个普通的Java类,一般来讲,该类继承了javax.servlet.http.HttpServlet类。因此,编译Servlet遵从编译一般java类的规则,具体的操作步骤如下:
编写Servlet
假设已经编写名为ServletTest.java的Servlet,其所处的包为test.servlet。并将其放置在/codolio/下,所以该Servlet所在的路径应为/codolio/test/servlet/ServletTest.java。该Servlet的源文件如下:
package test.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class ServletTest */ public class ServletTest extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=utf8"); request.setAttribute("message", "This is the message from servlet ServletTest"); ServletContext sc = this.getServletContext(); RequestDispatcher dispatcher = sc.getRequestDispatcher("/index.jsp"); dispatcher.forward(request, response); } }
编译Servlet
假设当前工作目录为/codolio,可以使用如下命令行进行编译该Servlet:javac -d dist -cp libs/servlet-api.jar test/servlet/ServletTest.java。该命令的具体解释如下:
(1)-d <dir>:javac的选项,用于指定生成的类文件的位置;
(2)-cp <路径>或者-classpath <路径>:javac的选项,用于指定查找用户类文件和注释处理程序的位置。在编译Servlet的时候,应该清楚Servlet依赖于$CATALINA_HOME/common/lib/servlet-api.jar包。为了编译方便,将该JAR包复制到/codolio/libs目录下。另外,还可以在CLASSPATH环境变量中添加该包的搜索路径来指定该JAR包,使用如下命令行:export CLASSPATH=$CLASSPATH:/codolio/libs/servlet-api.jar。
在编译完成后,在/codolio/dist/test/servlet目录下生成ServletTest.class文件,该文件即为编译完成后的Servlet。
(3)编译JSP
Tomcat默认使用JspServlet来完成JSP页面的转换、编译和执行工作。在处理JSP页面时,一般分作两步来处理:(1)将JSP页面转换成相应的Servlet(2)编译转换后的Servlet源文件为class文件。在$CATALINA_HOME/conf/web.xml部署描述符中存在如下配置:
<servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>xpoweredBy</param-name> <param-value>false</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> ... <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jspx</url-pattern> </servlet-mapping> ...
在Tomcat中,提供了一个名为JspC的类,位于$CATALINA_HOME/common/lib/jasper-compiler.jar包中,JspC是一个命令行JSP编译工具。虽然JSP页面经常位于一个容器运行环境中,但是有些时候由一个JSP页面来创建一个单纯的Servlet也很有用。JspC将由JSP页面向Servlet转换的核心过程封装在一个程序中,该程序不依赖于servlet引擎,并且允许你将JSP页面转换为一个等价的Java Servlet。
JspC类依赖于多个JAR包,在Tomcat 5.5.28目录结构中,其名称和位置列表如下:
commons-el.jar:位于$CATALINA_HOME/common/lib/下;
jasper-compiler.jar 位于$CATALINA_HOME/common/lib/下;
jasper-compiler-jdt.jar 位于$CATALINA_HOME/common/lib/下;
jasper-runtime.jar 位于$CATALINA_HOME/common/lib下;
jsp-api.jar 位于$CATALINA_HOME/common/lib下;
servlet-api.jar 位于$CATALINA_HOME/common/lib下;
ant.jar 该包可能需要另外下载,可以到Apache的官方网站或者别的链接上去下载。
注:在使用JspC进行JSP页面的转换、编译过程中,需要保证上述JAR包在CLASSPATH的搜索路径中。为了方便起见,将上述JAR包复制到/codolio/libs目录下。可以使用export命令或者使用java -cp参数来指定类的搜索路径,方法同上。
假设当前工作目录为/codolio,在该目录下存在一个名为test.jsp的JSP测试页面。在命令行中使用如下命令:java -cp libs/ant.jar:libs/commons-el.jar:libs/jasper-compiler.jar:libs/jasper-compiler-jdt.jar:libs/jasper-runtime.jar:libs/jsp-api.jar:libs/servlet-api.jar org.apache.jasper.JspC -compile -v -d dist -uriroot ./ -webxml dist/web.xml test.jsp。该命令的具体解释如下:
(1)-cp:指定类的搜索目录;
(2)-p <name>:目标package的名称;
(3)-c <name>:目标class的名称;
(4)-uriroot <dir>:将要被处理的页面的根目录,默认为包含JspC的目录;
(5)-webxml <file>:可以自动生成一个相关的web.xml;
(6)-v:输出详细信息;
(7)-compile:编译生成的Servlet;
(8)-classpath:覆盖java.class.path系统属性;
(9)-source <version>:设置编译器的-source参数,默认为1.4;
(10)-target <version>:设置编译器的-target参数,默认为1.4。
命令执行结束以后,在/codolio/dist目录下会生成由JSP页面转换而来的Servlet源文件和由Servlet编译而来的class文件,并在/codolio/dist目录下生成相应的web.xml部署描述符。
至此,手工编译Servlet和JSP的工作基本完成。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/codolio/archive/2010/01/11/5177236.aspx