Servlet 表单数据
GET 与 POST 的参数读取、中文乱码、多值参数与复选框。
Key PointsgetParameter 对 GET 查 query string、对 POST 读 body,两者用法一致;中文乱码要先定字符集再读参数。
HTML 表单
HTML
<form action="form" method="post">
姓名:<input type="text" name="name"><br>
密码:<input type="password" name="pass"><br>
性别:<input type="radio" name="sex" value="m" checked>男
<input type="radio" name="sex" value="f">女<br>
爱好:<input type="checkbox" name="hobby" value="read">阅读
<input type="checkbox" name="hobby" value="run">跑步<br>
城市:<select name="city">
<option value="bj">北京</option>
<option value="sh">上海</option>
</select><br>
<button type="submit">提交</button>
</form>读取参数
Java
@WebServlet("/form")
public class FormServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); // 必须在第一次读参数之前
resp.setContentType("text/plain;charset=UTF-8");
String name = req.getParameter("name");
String pass = req.getParameter("pass");
String sex = req.getParameter("sex");
String city = req.getParameter("city");
String[] hobbies = req.getParameterValues("hobby"); // 复选框是多值
try (PrintWriter out = resp.getWriter()) {
out.println("name=" + name);
out.println("pass=" + pass);
out.println("sex=" + sex);
out.println("city=" + city);
out.println("hobby=" + (hobbies == null ? "无" : String.join(",", hobbies)));
}
}
}Output
name=张三
pass=secret
sex=m
city=bj
hobby=read,runGET 与 POST 的差别
| POST | ||
|---|---|---|
| Where data lives | URL 的 query string | 请求体 |
| Visible in address bar | 是 | 否 |
| Size limit | 受 URL 长度限制 | 基本不受限 |
| Idempotent | 是,可缓存可收藏 | 否 |
| Encoding fix | 改 server.xml 的 URIEncoding | req.setCharacterEncoding |
setCharacterEncoding only affects the request body, not the GET query string, which is decoded by the connector. That is why POST handles Chinese while GET garbles it — either use POST consistently or set URIEncoding="UTF-8" on the connector.常见坑
- 重复读 body ——
getParameter只能读一次,读之前先解析成对象 - null 与空串 —— 未提交的参数是
null,提交空值是"",判断要分开写 - 复选框 —— 必须用
getParameterValues,用getParameter只拿到第一个
HTML 表单
HTML
<form action="form" method="post">
姓名:<input type="text" name="name"><br>
密码:<input type="password" name="pass"><br>
性别:<input type="radio" name="sex" value="m" checked>男
<input type="radio" name="sex" value="f">女<br>
爱好:<input type="checkbox" name="hobby" value="read">阅读
<input type="checkbox" name="hobby" value="run">跑步<br>
城市:<select name="city">
<option value="bj">北京</option>
<option value="sh">上海</option>
</select><br>
<button type="submit">提交</button>
</form>读取参数
Java
@WebServlet("/form")
public class FormServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); // 必须在第一次读参数之前
resp.setContentType("text/plain;charset=UTF-8");
String name = req.getParameter("name");
String pass = req.getParameter("pass");
String sex = req.getParameter("sex");
String city = req.getParameter("city");
String[] hobbies = req.getParameterValues("hobby"); // 复选框是多值
try (PrintWriter out = resp.getWriter()) {
out.println("name=" + name);
out.println("pass=" + pass);
out.println("sex=" + sex);
out.println("city=" + city);
out.println("hobby=" + (hobbies == null ? "无" : String.join(",", hobbies)));
}
}
}Output
name=张三
pass=secret
sex=m
city=bj
hobby=read,runGET 与 POST 的差别
| GET | POST | |
|---|---|---|
| 数据位置 | URL 的 query string | 请求体 |
| 地址栏可见 | 是 | 否 |
| 长度限制 | 受 URL 长度限制 | 基本不受限 |
| 幂等 | 是,可缓存可收藏 | 否 |
| 乱码修复 | 改 server.xml 的 URIEncoding | req.setCharacterEncoding |
setCharacterEncoding 只影响请求体,对 GET 的 query string 无效——GET 的编码由容器连接器决定。所以「POST 中文正常、GET 中文乱码」几乎总是这个原因,要么统一用 POST,要么在连接器上配 URIEncoding="UTF-8"。常见坑
- 重复读 body ——
getParameter只能读一次,读之前先解析成对象 - null 与空串 —— 未提交的参数是
null,提交空值是"",判断要分开写 - 复选框 —— 必须用
getParameterValues,用getParameter只拿到第一个