当前位置: 首页 > 图文教程 > Java技术 > J2EE > J2EE:孙鑫教你一步一步编写Java Servlet

J2EE
构建高性能J2EE应用的五种核心策略
初学者如何开发出一个高质量的J2EE系统
构建高性能J2EE应用的五种核心策略
J2EE项目登录方式的改进设计与实现
开发J2EE解决方案的八个步骤(1)
开发J2EE解决方案的八个步骤(2)
J2EE架构的6个最佳实践
J2EE事务并发控制策略总结(1)(转载)
J2EE事务并发控制策略总结(2)(转载)
J2EE事务并发控制策略总结(3)(转载)
J2EE应用中常见的反模式(anti-patterns)
j2ee 常用技术
J2EE常用Jar包含义
J2EE技术之JDBC连接各种数据库的写法(给初学者)
Flex连接J2EE技术选择
用JavaScript刷新框架子页面的方法
J2EE开发原则
java获取网络图片、java截屏、java创建缩略图
jsp生成验证码
java 彻底理解 byte char short int float long double

J2EE:孙鑫教你一步一步编写Java Servlet


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 492 ::
收藏到网摘: n/a

现在我们开始编写一个最简单的Servlet其功能就是向客户端输出一个字符串Hello World”。实例的开发主要有下列步骤。

 

 Step1:编写HelloWorldServlet

2-1  HelloWorldServlet.java

package org.sunxin.ch02.servlet;

import java.io.IOException;

import java.io.PrintWriter;

 

import javax.servlet.Servlet;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

public class HelloWorldServlet implements Servlet

{

    private ServletConfig config;

    public void destroy(){}

 

    public ServletConfig getServletConfig()

    {

        return config;

    }

   

    /**

     * 该方法很少使用,因此返回null即可。

     */

    public String getServletInfo()

    {      

        return null;

    }

 

    /**

     * ServletConfig对象由容器构造。容器在调用init()方法时,将其作为参数传给Servlet

     */

    public void init(ServletConfig config) throws ServletException

    {

        this.config = config;

    }

 

    public void service(ServletRequest req, ServletResponse res)

            throws ServletException, IOException

    {

        //得到PrintWriter对象。Servlet使用输出流来产生响应

        PrintWriter out=res.getWriter();

        //向客户端发送字符数据。

        out.println("Hello World");

        //关闭输出流

        out.close();

    }

}

Servlet中,主要的方法是service(),当客户端请求到来时,Servlet容器将调用Servlet实例的service()方法对请求进行处理。我们在service()方法中,首先通过ServletResponse类中的getWriter()方法调用得到一个PrintWriter类型的输出流对象out,然后调用out对象的println()方法向客户端发送字符串“Hello World”,最后关闭out对象。

Servlet容器调用Servlet实例对请求的处理过程如图2-2所示。

                                                                                                                                                                                                   

                                                                                                                                                                                     

 

 

 

2-2  Servlet容器调用Servlet实例对请求进行处理的全过程

Step2:编译HelloWorldServlet.java

打开命令提示符,转到HelloWorldServlet.java所在的目录%CATALINA_HOME%\ webapps\ch02\src下,然后执行

javac -d . HelloWorldServlet.java

大多数情况下,你会看到如图2-3所示的画面。

                                                                                                                                                                                              

                                                                                                                                                                                                      

 

 

 

 

2-3  编译HelloWorldServlet.java的出错信息

产生这些错误的原因是Java编译器没有找到javax.servlet包中的类。要解决这个问题,我们需要让Java编译器知道Servlet API库所在的位置。Tomcat在其发行版中已经包含了Servlet API库,是以JAR文件的形式提供的,这个JAR文件的完整路径名是:

%CATALINA_HOME%\lib\servlet-api.jar

我们只需要在系统的CLASSPATH环境变量下添加这个JAR文件的路径名就可以了

设置CLASSPATH环境变量的方法和第1章设置JAVA_HOME环境变量的方法是一样的,在笔者的机器上CLASSPATH环境变量的配置如下:

CLASSPATH=.;D:\OpenSource\apache-tomcat-6.0.16\lib\servlet-api.jar

关闭刚才打开的命令提示符窗口,重新打开一个新的命令提示符窗口,进入HelloWorldServlet.java所在的目录,再次执行:

javac -d . HelloWorldServlet.java

生成org\sunxin\ch02\servlet目录结构,以及在servlet子目录中的HelloWorldServlet.class文件。

如果你已经安装了J2EE SDK,那么在安装目录的lib子目录下有一个javaee.jar文件(J2EE 1.4以及之前的版本是j2ee.jar文件),其中包含了Servlet API库。你可以在CLASSPATH环境变量下添加javaee.jar所在的路径名,就不需要再配Tomcat中的servlet-api.jar了。配置了javaee.jar后,你还可以开发其他的J2EE应用。

Step3:部署HelloWorldServlet

ServletWeb应用程序中的一个组件。一个Web应用程序是由一组ServletHTML页面、类,以及其他的资源组成的运行在Web服务器上的完整的应用程序,以一种结构化的有层次的目录形式存在。组成Web应用程序的这些资源文件要部署在相应的目录层次中,根目录代表了整个Web应用程序的根。我们通常是将Web应用程序的目录放到%CATALINA_HOME%\webapps目录下,在webapps目录下的每一个子目录都是一个独立的Web应用程序,子目录的名字就是Web应用程序的名字,也称为Web应用程序的上下文根。用户通过Web应用程序的上下文根来访问Web应用程序中的资源,如图2-4示。

如果你要新建一个Web应用程序,可以在webapps目录下先建一个目录,在这个例子中,我们所建的目录是ch02,作为第一个Web应用程序的上下文根。Java开发的Web应用程序需要遵照一定的目录层次结构,在Servlet规范中定义了Web应用程序的目录层次结构,如图2-5所示。

                   

                                                                                                                                                                                                                          

 

 

 

 

2-4  多个Web应用程序和上下文根           2-5  Web应用程序的目录层次结构

Web应用程序的目录层次结构如表2-1所示。

2-1  Web应用程序的目录层次结构

   

   

\ch02

Web应用程序的根目录,属于此Web应用程序的所有文件都存放在这个目录下

\ch02\WEB-INF

存放Web应用程序的部署描述符文件web.xml

\ch02\WEB-INF\classes

存放Servlet和其他有用的类文件

\ch02\WEB-INF\lib

存放Web应用程序需要用到的JAR文件,这些JAR文件中可以包含ServletBean和其他有用的类文件

\ch02\WEB-INF\web.xml

web.xml文件包含Web应用程序的配置和部署信息

 

 

 

 

 

 

 

 

 

 

 

从表2-1中可以看到,WEB-INF目录下的classeslib目录都可以存放Java的类文件,Servlet容器运行时,Web应用程序的类加载器将首先加载classes目录下的,其次才是lib目录下的类。如果这两个目录下存在同名的类,起作用的将是classes目录下的类。

在表2-1中,我们还可以看到一个特殊的目录WEB-INF,注意在书写时不要写错,所有字母都要大写。说这个目录特殊,是因为这个目录并不属于Web应用程序可以访问的上下文路径的一部分,对客户端来说,这个目录是不可见的。如果你将index.html文件放到WEB-INF目录下,对于客户端是无法通过下面的方式访问到这个文件的:

http://localhost:8080/ch02/WEB-INF/index.html

不过,WEB-INF目录下的内容对于Servlet代码是可见的,在Servlet代码中可以通过调用ServletContext对象中的getResource()或者getResourceAsStream()方法来访问WEB-INF目录下的资源,也可以使用RequestDispatcher调用(参见第2.6节)将WEB-INF目录下的内容呈现给客户端

如果我们想要在Servlet代码中访问保存在文件中的配置信息,而又不希望这些配置信息被客户端访问到,就可以把这个文件放到WEB-INF目录下。

%CATALINA_HOME%\webapps\ch02目录下新建一个目录WEB-INF,进入WEB-INF目录,新建一个classes目录,整个目录结构是:

%CATALINA_HOME%\webapps\ch02\WEB-INF\classes

将编译生成的HelloWorldServlet.class文件连同所在的包一起放到WEB-INF\classes目录下。

接下来,我们需要部署这个ServletWeb应用程序的配置和部署是通过web.xml文件来完成的。web.xml文件被称为Web应用程序的部署描述符,它可以包含如下的配置和部署信息:

?  ServletContext的初始化参数

?  Session的配置

?  Servlet/JSP的定义和映射

?  应用程序生命周期监听器类

?  过滤器定义和过滤器映射

?  MIME类型映射

?  欢迎文件列表

?  错误页面

?  语言环境和编码映射

?  声明式安全配置

?  JSP配置

我们所编写的web.xml文件必须是格式良好的XML。用记事本或者UltraEdit等文本编辑工具编写web.xml文件,内容如例2-2所示。

2-2  web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5"

    xmlns="http://java.sun.com/xml/ns/javaee"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

 

    <servlet>

        <servlet-name>HelloWorldServlet</servlet-name>

        <servlet-class>

org.sunxin.ch02.servlet.HelloWorldServlet

</servlet-class>

    </servlet>

 

    <servlet-mapping>

        <servlet-name>HelloWorldServlet</servlet-name>

        <url-pattern>/helloworld</url-pattern>

    </servlet-mapping>

</web-app>

第一行是XML声明,接下来在根元素<web-app>上声明了使用的XML Schema的版本。这段代码是固定的,你无须记忆它,只要知道复制/粘贴就可以了。

注意代码中以粗体显示的部分,这部分代码使用了<servlet><servlet-mapping>元素,以及它们的子元素来部署HelloWorldServlet。在web.xml文件中,可以包含多个<servlet><servlet-mapping>元素,用于部署多个Servlet

<servlet>元素用于声明Servlet<servlet-name>子元素用于指定Servlet的名字,在同一个Web应用程序中,每一个Servlet的名字必须是唯一的,该元素的内容不能为空。<servlet-class>子元素用于指定Servlet类的完整限定名(如果有包名,要同时给出包名)。

<servlet-mapping>元素用于在ServletURL样式之间定义一个映射。它的子元素<servlet-name>指定的Servlet名字必须和<servlet>元素中的子元素<servlet-name>给出的名字相同。<url-pattern>子元素用于指定对应于ServletURL路径,该路径是相对于Web应用程序上下文根的路径。

经过这样的配置之后,我们可以在浏览器的地址栏中输入http://localhost:8080/ ch02/helloworld来访问HelloWorldServlet。当Servlet容器接收到/ch02/helloworld的请求后,就会将发送给ch02 Web应用程序的Context(参见第1.6节),ch02 Web应用程序的Context首先移除该Web应用程序上下文路径的前缀/ch02,然后将剩余部分与web.xml文件中配置的<url-pattern>元素的内容相比较,找到对应的Servlet名字为HelloWorldServlet,再根据这个名字找到HelloWorldServlet类,进而实例化这个类,对请求进行处理。

将编写好的web.xml文件保存到%CATALINA_HOME%\webapps\ch02\WEB-INF目录下。读者也可以将%CATALINA_HOME%\webapps\ROOT\WEB-INF目录下的web.xml复制一份,存放到%CATALINA_HOME%\webapps\ch02\WEB-INF目录下,这个文件的内容如下:

<?xml version="1.0" encoding="ISO-8859-1"?>

 

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun. com/xml/ns/javaee/web-app_2_5.xsd"

   version="2.5">

 

  <display-name>Welcome to Tomcat</display-name>

  <description>

     Welcome to Tomcat

  </description>

 

</web-app>

然后编辑这个文件,添加HelloWorldServlet的配置,如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>

 

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun. com/xml/ns/javaee/web-app_2_5.xsd"

   version="2.5">

 

  <display-name>Welcome to Tomcat</display-name>

  <description>

     Welcome to Tomcat

  </description>

 

  <servlet>

    <servlet-name>HelloWorldServlet</servlet-name>

    <servlet-class>

org.sunxin.ch02.servlet.HelloWorldServlet

</servlet-class>

  </servlet>

 

  <servlet-mapping>

    <servlet-name>HelloWorldServlet</servlet-name>

    <url-pattern>/helloworld</url-pattern>

  </servlet-mapping>

 

</web-app>


%CATALINA_HOME%\webapps\ROOT目录是Tomcat默认的Web应用程序的起始路径,当我们输入http://localhost:8080/时,访问的就是该目录下的Web应用程序资源。如果你将本例的Servlet部署在该目录下,访问时只需输入http://localhost:8080/helloworld即可。

 

Step4:访问HelloWorldServlet

当部署好Servlet之后,对客户端来说,访问Servlet和访问静态页面没有什么区别。为了让读者对Servlet的访问有一个较好的感性认识,在这里我们通过两种方式来访问SimpleHello

第一种方式,我们通过telnet工具来访问本例中的Servlet,具体操作步骤,读者可以参看附录B

首先确保Tomcat服务器正常启动了。打开命令提示符,输入

telnet localhost 8080

回车后,输入

GET /ch02/helloworld HTTP/1.1

Host: localhost

注意书写与空格。然后连续两个回车,你将看到如图2-6所示的画面。

第二种方式,通过浏览器访问Servlet,打开IE,在地址栏中输入:

http://localhost:8080/ch02/helloworld

注意在helloworld后面不要加斜杠(/),然后回车,你将看到如图2-7所示的画面。

          

 

 

 

 

 

 

2-6  使用telnet工具与Servlet交互的信息    2-7  使用IE访问HelloWorldServlet

 

 

          在访问ServletJSP的时候,Servlet的名字和JSP的文件名都是区分大小写的,对于本例  来 说,如果你输入的是HelloWorld,那么Tomcat服务器会给出404的错误代码,提示“The  requested resource (/ch02/HelloWorld) is not available”。

Web应用程序的开发分为设计开发与配置部署两个阶段。通过部署,实现了组件与组件之间的松耦合,降低了Web应用程序维护的难度。在本例中,为Servlet指定了一个名字和URL映射,其他的组件或页面可以使用URL来调用这个Servlet,一旦Servlet发生了改动,例如,整个类被替换、重新命名等,只需修改web.xml文件中<servlet-class>元素的内容,在设计开发阶段确定的程序结构与代码不需要做任何的改动,降低了程序维护的难度。当然,事物都有两面性,在享受好处的同时,也需要我们花费额外的时间和精力去了解和掌握部署过程。