Servlets - 表单数据

您一定遇到过许多需要将一些信息从浏览器传递到 Web 服务器并最终传递到后端程序的情况。浏览器使用两种方法将这些信息传递给 Web 服务器。这些方法是 GET 方法和 POST 方法。

GET 方法

GET 方法将编码的用户信息附加到页面请求中发送。页面和编码的信息由 ?(问号)符号分隔,如下所示 −

http://www.test.com/hello?key1 = value1&key2 = value2

GET 方法是将信息从浏览器传递到 Web 服务器的默认方法,它会生成一个长字符串,该字符串显示在浏览器的 Location:box 中。如果您有密码或其他敏感信息要传递给服务器,切勿使用 GET 方法。 GET 方法有大小限制:请求字符串中只能使用 1024 个字符。

此信息使用 QUERY_STRING 标头传递,可通过 QUERY_STRING 环境变量访问,Servlet 使用 doGet() 方法处理此类请求。

POST 方法

将信息传递给后端程序的更可靠方法是 POST 方法。该方法以与 GET 方法完全相同的方式打包信息,但它不是将其作为 URL 中 ?(问号)后的文本字符串发送,而是将其作为单独的消息发送。此消息以标准输入的形式发送到后端程序,您可以解析并用于处理。 Servlet 使用 doPost() 方法处理此类请求。

使用 Servlet 读取表单数据

Servlet 根据情况使用以下方法自动处理表单数据解析 −

  • getParameter() − 调用 request.getParameter() 方法获取表单参数的值。

  • getParameterValues() − 如果参数出现多次并返回多个值(例如复选框),则调用此方法。

  • getParameterNames() −如果您想要当前请求中所有参数的完整列表,请调用此方法。

使用 URL 的 GET 方法示例

这是一个简单的 URL,它将使用 GET 方法将两个值传递给 HelloForm 程序。

http://localhost:8080/HelloForm?first_name = ZARA&last_name = ALI

下面给出的是 HelloForm.java servlet 程序,用于处理 Web 浏览器提供的输入。我们将使用 getParameter() 方法,该方法可以非常轻松地访问传递的信息 −

// 导入所需的 Java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

// 扩展 HttpServlet 类
public class HelloForm extends HttpServlet {
 
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      // 设置响应内容类型
      response.setContentType("text/html");

      PrintWriter out = response.getWriter();
      String title = "Using GET Method to Read Form Data";
      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">";
         
      out.println(docType +
         "<html>" ++
            "<head><title>" + title + "</title></head>" ++
            "<body bgcolor = \"#f0f0f0\">" ++
               "<h1 align = \"center\">" + title + "</h1>" ++
               "<ul>" ++
                  "  <li><b>First Name</b>: "
                  + request.getParameter("first_name") + "" ++
                  "  <li><b>Last Name</b>: "
                  + request.getParameter("last_name") + "" ++
               "</ul>" ++
            "</body>" +
         "</html>"
      );
   }
}

假设您的环境已正确设置,请按如下方式编译 HelloForm.java −

$ javac HelloForm.java

如果一切顺利,上述编译将生成 HelloForm.class 文件。接下来,您必须将此类文件复制到 <Tomcat-installationdirectory>/webapps/ROOT/WEB-INF/classes 中,并在位于 <Tomcat-installation-directory>/webapps/ROOT/WEB-INF/ 的 web.xml 文件中创建以下条目

<servlet>
   <servlet-name>HelloForm</servlet-name>
   <servlet-class>HelloForm</servlet-class>
</servlet>

<servlet-mapping>
   <servlet-name>HelloForm</servlet-name>
   <url-pattern>/HelloForm</url-pattern>
</servlet-mapping>

现在在浏览器的 Location:box 中输入 http://localhost:8080/HelloForm?first_name=ZARA&last_name=ALI,并确保在浏览器中执行上述命令之前已启动 tomcat 服务器。这将生成以下结果 −

使用 GET 方法读取表单数据

  • First Name: ZARA
  • Last Name: ALI

使用表单的 GET 方法示例

这是一个使用 HTML 表单和提交按钮传递两个值的简单示例。我们将使用相同的 Servlet HelloForm 来处理此输入。

<html>
   <body>
      <form action = "HelloForm" method = "GET">
         First Name: <input type = "text" name = "first_name">
         <br />
         Last Name: <input type = "text" name = "last_name" />
         <input type = "submit" value = "Submit" />
      </form>
   </body>
</html>

将此 HTML 保存在文件 Hello.htm 中,并将其放在 <Tomcat-installationdirectory>/webapps/ROOT 目录中。当您访问 http://localhost:8080/Hello.htm 时,以下是上述表单的实际输出。

First Name: Last Name:

尝试输入名字和姓氏,然后单击提交按钮以在运行 tomcat 的本地计算机上查看结果。根据提供的输入,它将生成与上述示例中提到的类似的结果。

使用表单的 POST 方法示例

让我们对上面的 servlet 进行一些修改,以便它可以处理 GET 和 POST 方法。以下是 HelloForm.java servlet 程序,用于使用 GET 或 POST 方法处理 Web 浏览器提供的输入。

// 导入所需的 Java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

// 扩展 HttpServlet 类
public class HelloForm extends HttpServlet {

   // 处理 GET 方法请求的方法。
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      // 设置响应内容类型
      response.setContentType("text/html");

      PrintWriter out = response.getWriter();
      String title = "Using GET Method to Read Form Data";
      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " +
         "transitional//en\">";
         
      out.println(docType +
         "<html>" ++
            "<head><title>" + title + "</title></head>" ++
            "<body bgcolor = \"#f0f0f0\">" ++
               "<h1 align = \"center\">" + title + "</h1>" ++
               "<ul>" ++
                  "  <li><b>First Name</b>: "
                  + request.getParameter("first_name") + "" ++
                  "  <li><b>Last Name</b>: "
                  + request.getParameter("last_name") + "" ++
               "</ul>" ++
            "</body>"
         "</html>"
      );
   }

   // 处理 POST 方法请求的方法。
   public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

      doGet(request, response);
   }
}

现在编译并部署上述 Servlet,并使用 Hello.htm 以 POST 方法进行测试,如下所示 −

<html>
   <body>
      <form action = "HelloForm" method = "POST">
         First Name: <input type = "text" name = "first_name">
         <br />
         Last Name: <input type = "text" name = "last_name" />
         <input type = "submit" value = "Submit" />
      </form>
   </body>
</html>

这是上述表单的实际输出,尝试输入名字和姓氏,然后单击提交按钮以在运行 tomcat 的本地计算机上查看结果。

First Name: Last Name:

根据提供的输入,它将生成与上述示例中提到的类似的结果。

将复选框数据传递给 Servlet 程序

当需要选择多个选项时,使用复选框。

以下是带有两个复选框的表单的示例 HTML 代码 CheckBox.htm

<html>
   <body>
      <form action = "CheckBox" method = "POST" target = "_blank">
         <input type = "checkbox" name = "maths" checked = "checked" /> Maths
         <input type = "checkbox" name = "physics"  /> Physics
         <input type = "checkbox" name = "chemistry" checked = "checked" /> 
                                          Chemistry
         <input type = "submit" value = "Select Subject" />
      </form>
   </body>
</html>

此代码的结果如下

Maths Physics Chemistry

下面给出的是 CheckBox.java servlet 程序,用于处理 Web 浏览器为复选框按钮提供的输入。

// 导入所需的 Java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

// 扩展 HttpServlet 类
public class CheckBox extends HttpServlet {
 
   // 处理 GET 方法请求的方法。
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      // 设置响应内容类型
      response.setContentType("text/html");

      PrintWriter out = response.getWriter();
      String title = "Reading Checkbox Data";
      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">";

      out.println(docType +
         "<html>" ++
            "<head><title>" + title + "</title></head>" ++
            "<body bgcolor = \"#f0f0f0\">" ++
               "<h1 align = \"center\">" + title + "</h1>" ++
               "<ul>" ++
                  "  <li><b>Maths Flag : </b>: "
                  + request.getParameter("maths") + "" ++
                  "  <li><b>Physics Flag: </b>: "
                  + request.getParameter("physics") + "" ++
                  "  <li><b>Chemistry Flag: </b>: "
                  + request.getParameter("chemistry") + "" ++
               "</ul>" ++
            "</body>"
         "</html>"
      );
   }

   // 处理 POST 方法请求的方法。
   public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      doGet(request, response);
   }
}

对于上述示例,它将显示以下结果 −

读取复选框数据

  • Maths Flag : : on
  • Physics Flag: : null
  • Chemistry Flag: : on

读取所有表单参数

以下是使用 HttpServletRequest 的 getParameterNames() 方法读取所有可用表单参数的通用示例。此方法返回一个枚举,其中包含未指定顺序的参数名称

一旦我们有了枚举,我们就可以以标准方式循环枚举,方法是使用 hasMoreElements() 方法确定何时停止,并使用 nextElement() 方法获取每个参数名称。

// 导入所需的 Java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

// 扩展 HttpServlet 类
public class ReadParams extends HttpServlet {
 
   // 处理 GET 方法请求的方法。
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      // 设置响应内容类型
      response.setContentType("text/html");

      PrintWriter out = response.getWriter();
      String title = "Reading All Form Parameters";
      String docType =
         "<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">";

      out.println(docType +
         "<html>" ++
         "<head><title>" + title + "</title></head>" ++
         "<body bgcolor = \"#f0f0f0\">" ++
         "<h1 align = \"center\">" + title + "</h1>" ++
         "<table width = \"100%\" border = \"1\" align = \"center\">" ++
         "<tr bgcolor = \"#949494\">" ++
            "<th>Param Name</th>"
            "<th>Param Value(s)</th>
"+
         "</tr>
"
      );

      Enumeration paramNames = request.getParameterNames();

      while(paramNames.hasMoreElements()) {
         String paramName = (String)paramNames.nextElement();
         out.print("<tr><td>" + paramName + "</td>
<td>");
         String[] paramValues = request.getParameterValues(paramName);

         // 读取单值数据
         if (paramValues.length == 1) {
            String paramValue = paramValues[0];
            if (paramValue.length() == 0)
               out.println("<i>No Value</i>");
               else
               out.println(paramValue);
         } else {
            // 读取多值数据
            out.println("<ul>");

            for(int i = 0; i < paramValues.length; i++) {
               out.println("<li>" + paramValues[i]);
            }
            out.println("</ul>");
         }
      }
      out.println("</tr>
</table>
</body></html>");
   }
   
   // 处理 POST 方法请求的方法。
   public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      
      doGet(request, response);
   }
}

现在,使用以下形式尝试上述 servlet −

<html>
   <body>
      <form action = "ReadParams" method = "POST" target = "_blank">
         <input type = "checkbox" name = "maths" checked = "checked" /> Maths
         <input type = "checkbox" name = "physics"  /> Physics
         <input type = "checkbox" name = "chemistry" checked = "checked" /> Chem
         <input type = "submit" value = "Select Subject" />
      </form>
   </body>
</html>

现在使用上述表单调用 servlet 将生成以下结果 −

读取所有表单参数

参数名称 参数值
maths on
chemistry on

您可以尝试上述 servlet 来读取具有其他对象(如文本框、单选按钮或下拉框等)的任何其他表单的数据。