Servlet/JSP深入详解
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2 几个实例

在这一节,我们将通过三个例子来帮助读者更好地理解Servlet的开发与部署过程,以及Servlet中主要接口与类的使用。在讲解实例时,我们将通过一步一步地操作来完成整个实例。

2.2.1 实例一:WelcomeServlet

在本例中,我们将编写一个带表单的HTML页面,表单中提供了一个文本输入控件,让用户输入他/她的姓名,然后提交给Servlet进行处理。在Servlet中,我们从提交的表单信息中取出用户姓名,然后加上欢迎信息输出到客户端。欢迎信息作为Servlet的初始化参数在web.xml文件中配置。

实例的开发主要有下列步骤。

开发步骤

Step1:编写welcome.html

用记事本或者UltraEdit等文本编辑工具(读者也可以使用专门的网页编辑软件)编写welcome. html,将编写好的welcome.html文件放到%CATALINA_HOME%\webapps\ch02目录下。完整的代码如例2-3所示。

例2-3 welcome.html

        <html>
            <head>
              <title>欢迎您!</title>
            </head>
            <body>
              <form action="welcome" method="get">
                  请输入用户名:<input type="text" name="username"><br>
                  <input type="submit" value="提交">
              </form>
            </body>
        </html>

在HTML代码中,我们先假定对此表单进行处理的Servlet是welcome,表单采用的提交方法是get。

Step2:编写WelcomeServlet类

为了简化Servlet的编写,Servlet API给我们提供了支持HTTP协议的javax.servlet.http.HttpServlet类,我们只需要从HttpServlet类派生一个子类,在子类中完成相应的功能就可以了。

编写WelcomeServlet类,从HttpServlet类继承,重写doGet()方法。将编写好的WelcomeServlet.java源文件放到%CATALINA_HOME%\ webapps\ch02\src目录下。完整的源代码如例2-4所示。

例2-4 WelcomeServlet.java

        1.  package org.sunxin.ch02.servlet;
        2.
        3.  import java.io.IOException;
        4.  import java.io.PrintWriter;
        5.
        6.  import javax.servlet.ServletException;
        7.  import javax.servlet.http.HttpServlet;
        8.  import javax.servlet.http.HttpServletRequest;
        9.  import javax.servlet.http.HttpServletResponse;
        10.
        11. public class WelcomeServlet extends HttpServlet
        12. {
        13.    private String greeting;
        14.
        15.    public void init()
        16.    {
        17.        greeting = getInitParameter("greeting");
        18.        //greeting = getServletConfig().getInitParameter("greeting");
        19.    }
        20.
        21.    public void doGet(HttpServletRequest req,HttpServletResponse resp)
        22.              throws ServletException,IOException
        23.    {
        24.        req.setCharacterEncoding("gb2312");
        25.        String username=req.getParameter("username");
        26.        String welcomeInfo=greeting + ", " + user;
        27.
        28.        resp.setContentType("text/html");
        29.
        30.        PrintWriter out=resp.getWriter();
        31.
        32.        out.println("<html><head><title>");
        33.        out.println("Welcome Page");
        34.        out.println("</title></head>");
        35.        out.println("<body>");
        36.        out.println(welcomeInfo);
        37.        out.println("</body></html>");
        38.        out.close();
        39.    }
        40. }

例2-4代码的第17行,我们调用getInitParameter()方法得到初始化参数greeting的值,这个调用和第18行注释的代码是等价的。从HttpServlet继承的getInitParameter()方法实际上也是调用ServletConfig对象的getInitParameter()方法来得到初始化参数的。

由于用户可能会输入中文用户名,因此我们在代码的第24行设置请求正文使用的字符编码是gb2312。

前面我们介绍过,HttpServletRequest对象封装了客户端的请求信息,要获取请求中某个参数的值,可以调用HttpServletRequest对象的getParameter()方法,传递参数的名字。在代码的第25行,我们调用req.getParameter("username")获取到用户输入的用户名。注意getParameter()方法的参数“username”和表单中用于输入用户姓名的文本输入控件的名字“username”必须是一样的。

第26行,我们用取出的用户名构造一个欢迎字符串。第28行,设置响应内容的MIME类型为text/html。第32~38行,都是在输出HTML代码,第36行,将欢迎信息放到<body>元素的开始标签和结束标签之间输出。第35行,关闭out对象。

Step3:编译WelcomeServlet.java

打开命令提示符,进入%CATALINA_HOME%\webapps\ch02\src目录,然后执行:

        javac -d ..\WEB-INF\classes WelcomeServlet.java

在WEB-INF\classes\org\sunxin\ch02\servlet目录中生成类文件WelcomeServlet.class。

Step4:部署WelcomeServlet类

用记事本或UltraEdit打开%CATALINA_HOME%\webapps\ch02\WEB-INF目录下的web.xml文件,添加对本例中的Servlet的配置,完整的内容如例2-5所示。

例2-5 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>
            <servlet>
              <servlet-name>WelcomeServlet</servlet-name>
              <servlet-class>
                  org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
              <init-param>
                  <param-name>greeting</param-name>
                  <param-value>Welcome you</param-value>
              </init-param>
          </servlet>
          <servlet-mapping>
              <servlet-name>WelcomeServlet</servlet-name>
              <url-pattern>/welcome</url-pattern>
          </servlet-mapping>
        </web-app>

新增加的内容以粗体显示。我们在<servlet>元素内部使用<init-param>子元素来为WelcomeServlet配置的初始化参数,在例2-4的init()方法中,有这样一句代码:

        greeting = getInitParameter("greeting");

这句代码的作用就是获取此处配置的greeting初始化参数的值。

注意,在Servlet 2.2和Servlet 2.3规范中,web.xml文件使用DTD来定义文档的结构。在Servlet 2.2规范中,web.xml的文档类型声明如下:

        <!DOCTYPE web-app
            PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
            "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

在Servlet 2.3规范中,web.xml的文档类型声明如下:

        <!DOCTYPE web-app
            PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd">

因为是用DTD来定义web.xml文档的结构,所以元素出现的次序是有严格限制的,在这两个版本中,<servlet>元素必须出现在<servlet-mapping>元素之前。而从Servlet 2.4规范开始,web.xml文件改为用XML Schema来定义文档的结构,其中一个好处就是元素出现的次序不再有严格的限定。如果我们开发的Web应用程序需要运行在支持低版本的Servlet规范的Web服务器中运行,那么需要将web.xml文件修改为如例2-6所示。

例2-6 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>
              <servlet-name>WelcomeServlet</servlet-name>
              <servlet-class>
                  org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
              <init-param>
                  <param-name>greeting</param-name>
                  <param-value>Welcome you</param-value>
              </init-param>
          </servlet>
          <servlet-mapping>
              <servlet-name>HelloWorldServlet</servlet-name>
              <url-pattern>/helloworld</url-pattern>
          </servlet-mapping>
          <servlet-mapping>
              <servlet-name>WelcomeServlet</servlet-name>
              <url-pattern>/welcome</url-pattern>
          </servlet-mapping>
        </web-app>

注意文件中元素出现的顺序。

Step5:访问WelcomeServlet

启动Tomcat服务器,打开IE浏览器,在地址栏中输入:

      http://localhost:8080/ch02/welcome.html

出现页面后,在文本输入控件中输入用户姓名,如图2-8所示。

图2-8 welcome.html页面

单击“提交”按钮,你将看到如图2-9所示的页面。

图2-9 以GET方式提交后WelcomeServlet输出的响应信息

注意IE浏览器的地址栏部分,因为welcome.html页面采用的表单提交方法是get,所以提交的数据被附加到请求URL的末端,作为查询字符串发送到服务器端。采用get方法提交表单,和我们直接在浏览器的地址栏中输入附加了查询字符串的URL的效果是一样的。在本例中,我们也可以通过直接输入如下形式的URL来提交数据:

      http://localhost:8080/ch02/welcome?username=zhangsan

Step6:将提交方法改为post

将例2-3的welcome.html中的表单提交方法改为post,如下:

        <form action="welcome" method="post">

保存后,打开浏览器,在地址栏中输入http://localhost:8080/ch02/welcome.html,输入用户名后,单击“提交”按钮,你将看到如图2-10所示的页面。

图2-10 WelcomeServlet无法处理post请求,返回HTTP 405错误信息

这是因为我们在WelcomeServlet类中没有重写doPost()方法,而HttpServlet类的doPost()方法的默认实现是返回状态代码为405的HTTP错误,表示对于指定资源的请求方法不被允许。如果要对post请求做出响应,需要在WelcomeServlet这个类中覆盖基类的doPost()方法。我们修改例2-4的WelcomeServlet.java,如例2-7所示。

例2-7 修改后的WelcomeServlet.java

        package org.sunxin.ch02.servlet;
        import java.io.IOException;
        import java.io.PrintWriter;
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        public class WelcomeServlet extends HttpServlet
        {
            private String greeting;
            public void init()
            {
              greeting = getInitParameter("greeting");
              //greeting = getServletConfig().getInitParameter("greeting");
            }
            public void doGet(HttpServletRequest req, HttpServletResponse resp)
          throws ServletException,IOException
{
    req.setCharacterEncoding("gb2312");
    String username=req.getParameter("username");
    String welcomeInfo=greeting + ", " + username;
    resp.setContentType("text/html");
    PrintWriter out=resp.getWriter();
    out.println("<html><head><title>");
    out.println("Welcome Page");
    out.println("</title></head>");
    out.println("<body>");
    out.println(welcomeInfo);
    out.println("</body></html>");
    out.close();
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException,IOException
{
    doGet(req,resp);
}
}

在doPost()方法中,直接调用了doGet()方法对post请求进行处理,这样,不管是get请求还是post请求,处理结果都是一样的。

按照Step3所示的方式编译WelcomeServlet.java。重启Tomcat服务器,在浏览器的地址栏中输入http://localhost:8080/ch02/welcome.html,输入用户名后,单击“提交”按钮,你将看到如图2-11所示的页面。

图2-11 post方式提交后WelcomeServlet输出的响应信息

注意IE浏览器的地址栏部分,因为现在welcome.html页面采用的表单提交方法是post,提交的数据作为请求正文的内容发送到服务器端,所以在URL中就看不到附加的请求数据了。通常在提交表单时,如果数据量较小,而又没有安全性的考虑(例如,提交的数据中没有密码等敏感信息),可以采用get方法提交表单。如果数据量较大,或者有安全方面的考虑,则应该采用post方法提交表单。

一旦你修改过Servlet类,要记着重新启动Tomcat,否则,对请求进行响应的仍然是已经驻留在内存中的先前的Servlet实例。如果要让运行中的Tomcat服务器自动加载修改过Servlet类,可以参看第3.1节。

2.2.2 实例二:OutputInfoServlet

在本例中,我们将编写一个Servlet,用于获取请求中的消息报头,并将这些报头的名称和值输出到客户端。此外,我们还利用ServletRequest接口中定义的方法获取客户端和服务器端的IP地址及端口号,并将这些信息输出到客户端。在这个Servlet中,我们还设置了响应的实体报头。实例的开发主要有下列步骤。

开发步骤

Step1:编写OutputInfoServlet类

将编写好的OutputInfoServlet.java源文件放到%CATALINA_HOME%\webapps\ch02\src目录下。完整的源代码如例2-8所示。

例2-8 OutputInfoServlet.java

        1.  package org.sunxin.ch02.servlet;
        2.
        3.  import java.io.IOException;
        4.  import java.io.PrintWriter;
        5.  import java.util.Enumeration;
        6.
        7.  import javax.servlet.ServletException;
        8.  import javax.servlet.http.HttpServlet;
        9.  import javax.servlet.http.HttpServletRequest;
        10. import javax.servlet.http.HttpServletResponse;
        11.
        12. public class OutputInfoServlet extends HttpServlet
        13. {
        14.    public void doGet(HttpServletRequest req,HttpServletResponse resp)
        15.              throws ServletException,IOException
        16.    {
        17.
        18.        resp.setContentType("text/html;charset=gb2312");
        19.
        20.        PrintWriter out=resp.getWriter();
        21.
        22.        Enumeration headNames=req.getHeaderNames();
        23.
        24.        out.println("<html><head>");
        25.        out.println("<title>Info Page</title>");
        26.        out.println("</head>");
        27.        out.println("<body><center>");
        28.
        29.        out.println("<table border=1 align=center>");
        30.        out.println("<caption>Servlet接收到的HTTP消息报头的信息</caption>");
        31.        out.println("<tr bgcolor=#999999>");
        32.        out.println("<th>消息报头的名字</th>");
        33.        out.println("<th>消息报头的值</th>");
        34.        out.println("</tr>");
        35.
        36.        while(headNames.hasMoreElements())
        37.        {
        38.           String name=(String)headNames.nextElement();
        39.           String value=req.getHeader(name);
        40.           out.println("<tr>");
        41.           out.println("<td>"+name+"</td>");
        42.           out.println("<td>"+value+"</td>");
        43.           out.println("</tr>");
        44.        }
        45.
        46.        out.println("</table><p>");
        47.
        48.        out.println("<table border=1 align=center>");
        49.        out.println("<caption>其他访问信息</caption>");
        50.
        51.        out.println("<tr>");
        52.        out.println("<td>客户端的IP地址</td>");
        53.        out.println("<td>"+req.getRemoteAddr()+"</td>");
        54.        out.println("</tr>");
        55.
        56.        out.println("<tr>");
        57.        out.println("<td>客户端的端口号</td>");
        58.        out.println("<td>"+req.getRemotePort()+"</td>");
        59.        out.println("</tr>");
        60.
        61.        out.println("<tr>");
        62.        out.println("<td>服务器端的IP地址</td>");
        63.        out.println("<td>"+req.getLocalAddr()+"</td>");
        64.        out.println("</tr>");
        65.
        66.        out.println("<tr>");
        67.        out.println("<td>服务器端的端口号</td>");
        68.        out.println("<td>"+req.getLocalPort()+"</td>");
        69.        out.println("</tr>");
        70.
        71.        out.println("</table>");
        72.
        73.        out.println("</center></body></html>");
        74.        out.close();
        75.    }
        76. }

在程序代码的第18行,设置响应内容的MIME类型为text/html,因为响应内容中包含了中文,所以设置字符编码方式为gb2312。要注意的是,这一句代码必须放在第20行代码的前面,否则将无法设置响应的字符编码,out对象将使用默认的字符编码ISO-8859-1。此外,还要注意的是在text/html和“;”之间不能有空格,即不能写成text/html ;charset=gb2312,否则浏览器将不能正确识别响应的内容类型。第22行,通过请求对象的getHeaderNames()方法调用,得到请求中包含的所有消息报头的名字的枚举集合。第29~34行,输出一个表格,设置表格的标题和表头。第36~44行,循环取出枚举集合中消息报头的名字,然后利用报头的名字调用请求对象的getHeader()方法得到对应的值,将报头的名字和值分别放到表格的单元格中。第48~71行,输出另一个表格,表格的内容是客户端和服务器端的IP地址和端口号。第53行,调用请求对象的getRemoteAddr()方法得到发送请求的客户端的IP地址。第58行,调用请求对象的getRemotePort()方法得到发送请求的客户端的端口号,这个方法是在Servlet 2.4规范中新增的方法。第63行,调用getLocalAddr()方法得到接收到请求的服务器端的IP地址,这个方法是在Servlet 2.4规范中新增的方法。第68行,调用请求对象的getLocalPort()方法得到接收到请求的服务器端的端口号,这个方法是在Servlet 2.4规范中新增的方法。

Step2:编译OutputInfoServlet.java

打开命令提示符,进入%CATALINA_HOME%\webapps\ch02\src目录,然后执行:

        javac -d ..\WEB-INF\classes OutputInfoServlet.java

在WEB-INF\classes\org\sunxin\ch02\servlet目录中生成类文件OutputInfoServlet.class。

Step3:部署OutputInfoServlet

编辑WEB-INF目录下的web.xml文件,添加对本例中的Servlet的配置,完整的内容如例2-9所示。

例2-9 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>
            <servlet>
              <servlet-name>WelcomeServlet</servlet-name>
              <servlet-class>
                  org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
              <init-param>
                  <param-name>greeting</param-name>
                  <param-value>Welcome you</param-value>
              </init-param>
          </servlet>
          <servlet-mapping>
              <servlet-name>WelcomeServlet</servlet-name>
              <url-pattern>/welcome</url-pattern>
          </servlet-mapping>
          <servlet>
              <servlet-name>OutputInfoServlet</servlet-name>
              <servlet-class>
                  org.sunxin.ch02.servlet.OutputInfoServlet </servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>OutputInfoServlet</servlet-name>
              <url-pattern>/info</url-pattern>
          </servlet-mapping>
        </web-app>

新增加的内容以粗体显示。

Step4:访问OutputInfoServlet

启动Tomcat服务器,打开IE浏览器,在地址栏中输入http://localhost:8080/ch02/info,你将看到如图2-12所示的页面。

图2-12 使用IE访问OutputInfoServlet

Step5:查看在响应中设置的实体报头

在本例(例2-8)的代码中,第18行我们调用:

        resp.setContentType("text/html;charset=gb2312");

将会设置HTTP响应的Content-Type实体报头。这个实体报头的信息是给客户端软件(通常是浏览器)看的,在页面中并不会体现出来。为了查看这句代码调用是否正确设置了Content-Type实体报头,我们可以利用telnet工具去访问本例中的OutputInfoServlet。

首先确保Tomcat服务器正常启动了。打开命令提示符,输入telnet localhost 8080,回车后,输入:

        GET /ch02/info HTTP/1.1
        Host: localhost

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

图2-13 使用telnet工具查看Content-Type实体报头的设置信息

注意图2-13中圆角矩形框中的内容,说明代码中对setContentType()方法的调用确实设置了Content-Type实体报头。

2.2.3 实例三:LoginServlet

在本例中,我们将编写一个登录页面,用户输入用户名和密码后,将表单提交给LoginServlet进行处理。在LoginServlet中,判断用户名和密码是否正确,如果正确,利用重定向向用户返回成功登录页面;如果失败,则向用户返回一个HTTP错误消息。实例的开发主要有下列步骤。

开发步骤

Step1:编写login.html

login.html用于向用户显示登录表单。在%CATALINA_HOME%\webapps\ch02目录下新建login.html,内容如例2-10所示。

例2-10 login.html

        <html>
            <head>
              <title>登录页面</title>
            </head>
            <body>
              <form action="login" method="post">
                  <table>
                    <tr>
                        <td>请输入用户名:</td>
                        <td><input type="text" name="username"></td>
                    </tr>
                    <tr>
                        <td>请输入密码:</td>
                        <td><input type="password" name="password"></td>
                    </tr>
                    <tr>
                        <td><input type="reset" value="重填"></td>
                        <td><input type="submit" value="登录"></td>
                    </tr>
                  </table>
              </form>
          </body>
        </html>

在HTML代码中,我们先假定对此表单进行处理的Servlet是login,因为提交的数据中包含了用户的密码,所以表单的提交方法我们采用post。

Step2:编写success.html

success.html用于向用户显示欢迎信息。在%CATALINA_HOME%\webapps\ch02目录下新建success.html,内容如例2-11所示。

例2-11 success.html

        <html>
            <head>
              <title>登录成功</title>
            </head>
            <body>
              登录成功,欢迎进入孙鑫的个人网站(www.sunxin.org)!
            </body>
        </html>

Step3:编写LoginServlet类

在%CATALINA_HOME%\webapps\ch02\src目录下新建LoginServlet.java,代码如例2-12所示。

例2-12 LoginServlet.java

        1.  package org.sunxin.ch02.servlet;
        2.
        3.  import java.io.IOException;
        4.
        5.  import javax.servlet.ServletException;
        6.  import javax.servlet.http.HttpServlet;
        7.  import javax.servlet.http.HttpServletRequest;
        8.  import javax.servlet.http.HttpServletResponse;
        9.
        10. public class LoginServlet extends HttpServlet
        11. {
        12.    public void doGet(HttpServletRequest req,HttpServletResponse resp)
        13.              throws ServletException,IOException
        14.    {
        15.
        16.        resp.setContentType("text/html;charset=gb2312");
        17.
        18.        String name=req.getParameter("username");
        19.        String pwd=req.getParameter("password");
        20.
        21.        if(name!=null && pwd!=null && name.equals("zhangsan") &&
        22.          pwd.equals("1234"))
        23.        {
        24.           resp.sendRedirect("success.html");
        25.        }
        26.        else
        27.        {
        28.           resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,"服务器忙,请稍后再登录!");
        29.        }
        30.
        31.    }
        32.
        33.    public void doPost(HttpServletRequest req,HttpServletResponse resp)
        34.              throws ServletException,IOException
        35.    {
        36.        doGet(req,resp);
        37.    }
        38. }

在代码的第18~19行,调用请求对象的getParameter()方法得到用户名和密码。第21行首先判断name和pwd是否为空,这是为了避免出现空指针异常,如果用户直接在浏览器的地址栏中输入URL访问这个Servlet而没有附加username和password查询字符串,name和pwd将为null;接下来判断名字是否是zhangsan,密码是否是1234。第24行,判断为真,调用响应对象的sendRedirect()方法将用户请求重定向到success.html页面。第28行,判断为假,调用响应对象的sendError()方法发送HTTP错误代码503(在HttpServletResponse接口中定义为静态常量SC_SERVICE_UNAVAILABLE),告诉用户“服务器忙,请稍后再登录”。

Step4:编译LoginServlet.java

打开命令提示符,进入%CATALINA_HOME%\webapps\ch02\src目录,然后执行:

        javac -d ..\WEB-INF\classes LoginServlet.java

在WEB-INF\classes\org\sunxin\ch02\servlet目录中生成类文件LoginServlet.class。

Step5:部署LoginServlet

编辑WEB-INF目录下的web.xml文件,添加对本例中的Servlet的配置,完整的内容如例2-13所示。

例2-13 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>
            <servlet>
              <servlet-name>WelcomeServlet</servlet-name>
              <servlet-class>
                    org.sunxin.ch02.servlet.WelcomeServlet </servlet-class>
              <init-param>
                  <param-name>greeting</param-name>
                  <param-value>Welcome you</param-value>
              </init-param>
            </servlet>
            <servlet-mapping>
              <servlet-name>WelcomeServlet</servlet-name>
              <url-pattern>/welcome</url-pattern>
            </servlet-mapping>
            <servlet>
              <servlet-name>OutputInfoServlet</servlet-name>
              <servlet-class>
                    org.sunxin.ch02.servlet.OutputInfoServlet </servlet-class>
            </servlet>
            <servlet-mapping>
              <servlet-name>OutputInfoServlet</servlet-name>
              <url-pattern>/info</url-pattern>
            </servlet-mapping>
            <servlet>
                <servlet-name>LoginServlet</servlet-name>
                <servlet-class>
                    org.sunxin.ch02.servlet.LoginServlet </servlet-class>
            </servlet>
            <servlet-mapping>
                <servlet-name>LoginServlet</servlet-name>
                <url-pattern>/login</url-pattern>
            </servlet-mapping>
        </web-app>

新增加的内容以粗体显示。

Step6:访问LoginServlet

启动Tomcat服务器,打开IE浏览器,在地址栏中输入http://localhost:8080/ch02/login.html,出现页面后,在文本输入控件中输入zhangsan,在口令输入控件中输入1234,单击“提交”按钮,将看到如图2-14所示的页面。

图2-14 登录成功页面

注意图2-14浏览器地址栏中的URL。

回到http://localhost:8080/ch02/login.html页面,重新输入其他的用户名或密码,单击“提交”按钮,将看到如图2-15所示的页面。

图2-15 用户名或密码错误,LoginServlet输出HTTP 503错误消息

注意图2-15中圆角矩形框中的内容,向用户显示的这些错误消息是我们在响应对象的sendError()方法中指定的。

请读者注意,在本例中,用户输入了错误的用户名或密码,LoginServlet向用户发送HTTP 503错误,这只是为了演示sendError()方法的使用,在实际开发过程中,应该给用户一个更友好的提示“用户名或密码错误,请重新输入”,或者“拒绝此用户登录”。