一、请求(Request )乱码
✅ 1. POST 请求参数乱码
原因:
-
客户端(浏览器)默认以 UTF-8 编码发送表单数据。
-
但 Tomcat 等服务器默认使用 ISO-8859-1 解码请求体(request body),导致中文乱码。
解决方案:
在读取参数前,设置 request 的字符编码为 UTF-8:
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
⚠️ 必须在调用
getParameter()之前设置,否则无效。
✅ 2. GET 请求参数乱码
原因:
-
GET 请求的参数附加在 URL 中(如
/login?name=张三)。 -
Tomcat 默认使用 ISO-8859-1 解码 URL 路径和查询字符串(query string)。
解决方案(任选其一):
方法①:手动重新编码(传统方式)
String name = request.getParameter("name"); // 此时是乱码(ISO-8859-1 编码)
// 先用 ISO-8859-1 获取原始字节,再用 UTF-8 重新解码
name = new String(name.getBytes("ISO-8859-1"), "UTF-8");
方法②:配置 Tomcat(推荐)
在 conf/server.xml 中,为 <Connector> 添加 URIEncoding="UTF-8":
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
✅ 配置后,所有 GET 请求参数将自动按 UTF-8 解码,无需代码处理。
二、响应(Response)乱码
即使请求参数正确,如果响应未设置编码,返回给浏览器的中文仍可能乱码。
✅ 设置响应编码:
// 方式1:设置字符流编码(推荐用于文本)
response.setContentType("text/html;charset=UTF-8");
// 方式2:单独设置字符编码(较少用)
response.setCharacterEncoding("UTF-8");
🔔 注意:
setContentType()会同时设置响应头Content-Type: text/html;charset=UTF-8,确保浏览器正确解码。
三、最佳实践建议
-
统一使用 UTF-8 编码(前端页面、数据库、Java 代码、服务器配置)。
-
在
web.xml或过滤器中统一设置 request/response 编码(避免每个 Servlet 重复写)。// 示例:通用编码过滤器 public void doFilter(ServletRequest req, ServletResponse res, ...) { req.setCharacterEncoding("UTF-8"); res.setContentType("text/html;charset=UTF-8"); chain.doFilter(req, res); } -
对于新项目,使用 Spring Boot 等框架,默认已处理好编码问题。