4.1.2 手工编写Servlet
在本节将给出一个如何通过手工方式编写Servlet的例子。这个例子完全脱离IDE,只使用记事本和Java编译器来完成Servlet的编写、编译和发布工作。
例子 : 手工编写Servlet
1. 程序分析说明
service方法可以处理所有的HTTP请求,而有时需要只处理某一种或几种HTTP请求,而HttpServlet类的doGet方法正好可满足这个要求。doGet方法被用来处理HTTP GET请求。直接通过浏览器地址栏访问Web资源就是发送HTTP GET请求。如果通过POST或其他的HTTP方法来访问只有doGet方法的Servlet,将会向客户端输出一个405错误“HTTP method POST is not supported by this URL”。在本例中的Servlet类将使用doGet方法来处理客户端的HTTP GET请求,并向客户端输出一个简单的字符串。
2. 建立目录结构
在编写Servlet之前,需要建立Servlet所在的目录结构。读者可按如下三步来建立Servlet目录结构。
(1)在<Tomcat安装目录>\webapps目录中建立一个mydemo目录
(2)在<Tomcat安装目录>\webapps:\mydemo目录中建立一个WEB-INF目录。
(3)在<Tomcat安装目录>\webapps:\mydemo\WEB-INF目录中建立一个classes目录。
3. 编写Servlet类
在<Tomcat安装目录>\webapps\mydemo目录中建立一个MyDoGet.java文件,并输入如下的代码:
package chapter4;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyDoGet extends HttpServlet
{
// 只处理HTTP GET请求
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// 设置Content-Type字段值
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 向客户端输出信息
out.println("doGet方法被调用!");
}
}
上面的代码使用HttpServletResponse接口的getWriter方法获得了一个PrintWriter对象,用来向客户端输出文本信息。并通过HttpServletResponse接口的setContextType方法设置了HTTP响应头的Content-Type字段值。
4. 编译Servlet类
编译MyDoGet类需要一个servlet-api.jar文件,这个文件可以在<Tomcat安装目录>\lib目录中找到,为了方便,可以将这个文件复制到<Tomcat安装目录>\webapps\mydemo目录中。然后打开【Windows控制台】,并进入<Tomcat安装目录>\webapps\mydemo目录,然后输入如下的命令来编译MyDoGet.java:
javac -classpath .;servlet-api.jar -d WEB-INF/classes MyDoGet.java
在成功执行上面的命令后,读者将会在<Tomcat安装目录>\webapps\mydemo\WEB-INF\classes\chapter4目录中看到一个MyDoGet.class文件。
5. 配置Servlet类
这是手工编写Servlet程序的最后一步。在<Tomcat安装目录>\webapps\mydemo\WEB-INF目录中建立一个web.xml文件,并输入如下的内容:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 开始配置MyDoGet -->
<servlet>
<servlet-name>MyDoGet</servlet-name>
<servlet-class>chapter4.MyDoGet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyDoGet</servlet-name>
<url-pattern>/ MyDoGet</url-pattern>
</servlet-mapping>
</web-app>
上面的配置代码中的开头部分(尤其是<web-app>标签的属性)很复杂,不过读者并不需要记这些东西,只需要找一个已经配置完的Java Web程序的例子,将其中web.xml文件中的相关内容复制过来即可。如在Tomcat中提供了一些Servlet的例子,读者可以在<Tomcat安装目录>\webapps\examples\WEB-INF目录找到一个已经配置完的web.xml文件。
在完成上面的几步后,可以通过<Tomcat安装目录>\bin\startup.bat命令来启动Tomcat,然后在IE地址栏中输入如下的URL来测试MyDoGet:
http://localhost:8080/mydemo/MyDoGet
在访问上面的URL后,将在IE中输出如图4.1所示的信息。
图4.1 MyDoGet的输出结果
6. 程序总结
在本例中将程序目录放在了<Tomcat安装目录>\webapps目录中,实际上,这是最简单的发布Java Web程序的方式。读者也可以将程序目录放在任何位置,如将mydemo目录放在D盘的根目录,然后打开<Tomcat安装目录>\conf\server.xml文件,找到<Host>元素,并使用<Context>子元素来发布程序,配置代码如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
... ...
<Context path="/newdemo" docBase="d:\mydemo" debug="0" />
... ...
</Host>
重新Tomcat后,可以通过http://localhost:8080/newdemo/MyDoGet来访问MyDoGet。在<Context>元素中,path属性表示Web程序的上下文路径,如果path属性值为空串,则表示Web站点的根目录。如下面的配置代码所示:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
... ...
<Context path="" docBase="d:\mydemo" debug="0" />
... ...
</Host>
如果使用上面的配置代码,可以通过http://localhost:8080/ MyDoGet来访问MyDoGet。要注意的是,要想设置Web程序的上下文路径为Web站点的根目录,path属性值必须为空串,而不能为“/”。
<Context>元素的docBase属性表示一个在磁盘上的实际存在的Web工程目录(可以是相对路径,也可以是绝对路径),或是一个*.war文件(也就是war包)。 如果docBase属性值是相对路径,那么这个路径将相对<Host>元素的appBase属性值所指的目录而言。在本例中,appBase属性值所指向的是<Tomcat安装目录>\webapps.。在<Host>元素中的unpackWARs属性值如果为true,所有放到webapps目录中的war包在发布时都会自动解压。而autoDeploy属性值如果为true,Tomcat在不重启的情况下,所复制到webapps目录中的Web工程目录或war包都会自动发布。
除了可以将<Context>作为<Host>的子元素外,还可以将<Context>元素提出来放到xml文件中。这些xml文件必须被放到<Tomcat安装目录>\conf\<引擎名>\<主机名>中。在Tomcat中,<引擎名>为Catalina,<主机名>就是<Host>元素中name属性的值,也就是localhost。因此,xml文件的存放目录为<Tomcat安装目录>\conf\Catalina\localhost。而且xml文件名就是上下文路径名,而<Context>目录的path属性将失效。如将hello.xml文件放到<Tomcat安装目录>\conf\Catalina\localhost目录中,内容如下:
<Context path="" docBase="d:\mydemo" debug="0" />
在IE地址栏中输入http://localhost:8080/hello/MyDoGet,就可以访问MyDoGet了。
在使用<Context>发布Web程序时应注意以下两点:
(1)<Context>元素必须是<Host>的子元素。
(2)<Context>元素在<Host>中可以存在多个,但每个<Context>元素中的path属性的值不能有重复,否则Tomcat在启动时将出现异常。