一个 Servlet 的小例子

Servlet 在 Java Web 的 MVC 模型中主要担当控制器的角色,然而 Servlet 却不仅仅只能做控制器。最初动态页面技术是 CGI,每过来一个 url 请求,调用一个对应的 cgi 程序,也就是创建一个子进程;该子进程负责生成 html 文档然后传送给浏览器等客户端。cgi 程序的缺点就是每一个请求都要创建进程,占用资源比较多,响应效率也比较低,后来 Java 就有了 Servlet 的技术。Servlet 可以说和 CGI 类似,是将 url 请求交给对应的 Java class 处理,在第一次使用的时候加载内存和初始化,后面相同的请求则复用该 class 。

担当 View 角色的 JSP,实际上也是在 web 容器中生成了相应的 servlet,客户端接收到的 html 文档就是对应的 servlet 输出出来的。在 MVC 中担当视图的 JSP 应该将业务逻辑(比如将用户名和密码插入数据库和判断等)交给 Model 层,而自己完全负责显示数据。Servlet 可以担当 Model 的作用,虽然在 MVC 中其不需要那么做。

这里写个小程序,在 login.html 中提交用户名和密码,然后将请求交给 LoginServlet,然后跳转到另外一个页面输出用户名和密码。该程序主要是体现 servlet 的用法,实际中可能根本就不会这么用,更可能的用法是在 servlet 连接数据库然后查询,或是调用其他 Java 服务,将业务逻辑的东西从 servlet 隔离出去。

项目组成

主要有四个文件:

  1. login.html : 负责搜集用户输入的用户名和密码,然后提交请求;
  2. welcome.jsp : 欢迎页面,显示 login.html 中输入的用户名和密码;
  3. test.LoginServlet : 负责从 request 中提出参数(用户名和密码),然后跳转到 welcome.jsp 页面;
  4. web.xml : 负责将 test.LoginServlet 和某个 url (比如 /login)建立映射,这样 url 请求才会传给 servlet;

程序代码

下面的代码仅供参考,Servlet 的模版文件可以在 Eclipse 中生成,可以省去很多闲工夫。

1) login.htm : 用户登陆

  1. <!doctype html>
  2. <meta charset="utf-8">
  3. <title>login page | java</title>
  4. body{
  5.     font-size: 12px;
  6. }
  7. </head>
  8.  
  9. <form action="login" method="POST">
  10. 用户:<input type="text" name="username"><br>
  11. 密码:<input type="text" name="password"><br>
  12. <input type="submit" value="登陆">
  13. </form>
  14. </body>
  15. </html><br>

2) welcome.jsp : 显示用户名和密码

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2. <!DOCTYPE html>
  3. <meta charset="utf-8">
  4. <title>welcom page | java</title>
  5. body{
  6.     font-size: 12px;
  7. }
  8. p{
  9.     line-height: 1.6em;
  10. }
  11. </head>
  12. <p>用户:${username} <br>密码:<%= request.getAttribute("password") %></p>
  13. </body>
  14. </html><br>

3) LoginServlet : 从 request 取出参数,处理编码,然后输出,最后跳转到 welcome.jsp;

  1. package test;
  2.  
  3. import java.io.IOException;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9.  
  10. /**
  11.  * Servlet implementation class LoginServlet
  12.  */
  13. @WebServlet("/LoginServlet")
  14. public class LoginServlet extends HttpServlet{
  15.     /**
  16.      * @see HttpServlet#HttpServlet()
  17.      */
  18.     public LoginServlet() {
  19.         super();
  20.     }
  21.      
  22.     /**
  23.      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  24.      */
  25.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  26.         System.out.println("GET process ... ");
  27.        
  28.         String username = request.getParameter("username");
  29.         String password = request.getParameter("password");
  30.         username = new String(username.getBytes("ISO-8859-1"), "UTF-8");    // request 默认编码: ISO-8859-1
  31.         password = new String(password.getBytes("ISO-8859-1"), "UTF-8");
  32.        
  33.         System.out.println(username + " " + password);
  34.        
  35.         request.setAttribute("username", username);
  36.         request.setAttribute("password", password);
  37.         request.getRequestDispatcher("/welcome.jsp").forward(request, response);
  38.     }
  39.      
  40.     /**
  41.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  42.      */
  43.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  44.         System.out.println("POST process ... ");
  45.         doGet(request, response);
  46.     }
  47.  
  48. }<br>

4) 配置 web.xml : 建立 url 和 servlet 的映射关系;

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance"">http://www.w3.org/2001/XMLSchema-instance"</a>
  3.     xmlns="<a href="http://java.sun.com/xml/ns/javaee"">http://java.sun.com/xml/ns/javaee"</a>
  4.     xmlns:web="<a href="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"">http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</a>
  5.     xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/javaee">http://java.sun.com/xml/ns/javaee</a> <a href="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"">http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"</a>
  6.     id="WebApp_ID" version="3.0">
  7.     <display-name>ServletTest</display-name>
  8.     <welcome-file-list>
  9.         <welcome-file>index.html</welcome-file>
  10.         <welcome-file>index.htm</welcome-file>
  11.         <welcome-file>index.jsp</welcome-file>
  12.     </welcome-file-list>
  13.  
  14.     <servlet>
  15.         <servlet-name>loginServlet</servlet-name>
  16.         <servlet-class>test.LoginServlet</servlet-class>
  17.     </servlet>
  18.     <servlet-mapping>
  19.         <servlet-name>loginServlet</servlet-name>
  20.         <url-pattern>/login</url-pattern>
  21.     </servlet-mapping>
  22. </web-app>

tips:

从上面的小程序中,me 们可以挖掘不少东西:

  1. HTTP 默认请求的字符编码是 ISO-8859-1,如果不作转换那么对于中文输入就会出现乱码;
  2. Java 中的字符编码转换:new String(username.getBytes("ISO-8859-1"), "UTF-8") 将 ISO-8859-1 编码转换为 UTF-8 编码字符串;
  3. Servlet 处理 POST 请求的 doPost 往往复用处理 GET 请求的 doGet ;
  4. 在 Servlet 中跳转到另外一个页面的方法 forward ;
  5. 在 Servlet 中获取参数 getParameter 以及设置参数 setAttribute 方法;

Tags: 

Article type: