Servlet 表单数据

Java Servlet 使用 doGet() 方法处理 HTTP GET 请求,使用 doPost() 方法处理 HTTP POST 请求

HTTP 请求方法

很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序

浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法

GET 方法

GET 方法向页面请求发送已编码的用户信息

页面和已编码的信息中间用 ? 字符分隔

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

GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中

如果要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法

GET 方法有大小限制:请求字符串中最多只能有 1024 个字符

这些信息使用 QUERY_STRING 头传递,并可以通过 QUERY_STRING 环境变量访问

Servlet 使用 doGet() 方法处理这种类型的请求

POST 方法

另一个向后台程序传递信息的比较可靠的方法是 POST 方法

POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息

消息以标准输出的形式传到后台程序,我们可以解析和使用这些标准输出

Servlet 使用 doPost() 方法处理这种类型的请求

使用 Servlet 读取表单数据

Servlet 处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析:

  • getParameter()调用 request.getParameter() 方法来获取表单参数的值
  • getParameterValues()如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框
  • getParameterNames()如果想要得到当前请求中的所有参数的完整列表,则调用该方法

使用 URL 的 GET 方法范例

下面是一个简单的 URL,将使用 GET 方法向 FormGetServlet 程序传递两个值:

http://localhost:8089/ServletTest/FormGetServlet?name=自学教程&url=www.runoops.com

使用 getParameter() 方法,可以很容易地访问传递的信息:

实例

package com.runoops.test;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloFormServlet
 */

public class FormGetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FormGetServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();
        String title = "使用 GET 方法读取表单数据 | 自学教程(runoops.com)";

        String docType = "<!DOCTYPE html>";
        out.println(docType +
            "<title>" + title + "</title>" +
            "<p>" + title + "</p>" +
            "<ul>" +
            "  <li><b>站点名</b>:"
            + request.getParameter("name") + "\n" +
            "  <li><b>网址</b>:"
            + request.getParameter("url") + "\n" +
            "</ul>");

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

在浏览器上输入 http://localhost:8089/ServletTest/FormGetServlet?name=自学教程&url=www.runoops.com

显示结果如下:

使用表单的 GET 方法实例

下面是一个简单的实例,使用 HTML 表单和提交按钮传递两个值。我们将使用相同的 FormGetServlet 来处理输入。

实例


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自学教程(runoops.com)</title>
</head>
<body>
<form action="FormGetServlet" method="GET">
网址名:<input type="text" name="name">
<br />
网址:<input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>

保存这个 HTML 到 form.html 文件中,尝试输入网址名和网址,然后点击"提交"按钮,Gif 演示如下:


使用表单的 POST 方法实例

让我们对上面的 Servlet 做小小的修改,以便它可以处理 GET 和 POST 方法。下面的 FormGetServlet.java Servlet 程序使用 GET 和 POST 方法处理由 Web 浏览器给出的输入。

注意:如果表单提交的数据中有中文数据则需要转码:

String name =new String(request.getParameter("name").getBytes("ISO8859-1"),"UTF-8");

实例

package com.runoops.test;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloFormServlet
 */

public class FormGetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FormGetServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();
        String title = "使用 POST 方法读取表单数据 | 自学教程(runoops.com)";
        
     // 处理中文
        String name =new String(request.getParameter("name").getBytes("ISO8859-1"),"UTF-8");

        String docType = "<!DOCTYPE html>";
        out.println(docType +
            "<title>" + title + "</title>" +
            "<p>" + title + "</p>" +
            "<ul>" +
            "  <li><b>站点名</b>:"
            + name + "\n" +
            "  <li><b>网址</b>:"
            + request.getParameter("url") + "\n" +
            "</ul>");

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

现在,编译部署上述的 Servlet,并使用带有 POST 方法的 form.html 进行测试,如下所示:

实例

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自学教程(runoops.com)</title>
</head>
<body>
<form action="FormGetServlet" method="POST">
网址名:<input type="text" name="name">
<br />
网址:<input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>

下面是上面表单的实际输出,尝试输入网址名和网址,然后点击"提交"按钮,Gif 演示如下:

您可以尝试使用上面的 Servlet 来读取其他的表单数据,比如文本框、单选按钮或下拉框等。


问题解答

如果用 getparameter() 获取中文只有问号:

String name =new String(request.getParameter("name").getBytes("ISO8859-1"),"UTF-8");

由于 tomcat8 默认编码是 utf-8,而这个过滤器把他当成 ISO8859-1 解码时(即解码了两次),就会出现问题,导致所有中文变成问号

所以我们只需要不使用这个过滤器就可以了。

也就是采用以下代码:

String name =new String(request.getParameter("name"));

这样就能正常显示中文。

对于解决 POST 中文乱码我们可以这样:

//请求解决乱码
response.setContentType("text/html;charset=utf-8");

//响应解决乱码
request.setCharacterEncoding("utf-8");

request.getParameterValues(String name) 是获得如 checkbox 类(名字相同,但值有多个)的数据,接收数组变量 ,如 checkobx 类型。

request.getParameter(String name) 是获得相应名的数据,如果有重复的名,则返回第一个的值,接收一般变量 ,如 text 类型。