JavaWeb 请求与响应乱码问题全面解决方案
JavaWeb 请求与响应乱码问题全面解决方案
乱码问题是 JavaWeb 开发中的常见挑战,主要源于字符编码不一致。以下是系统化的解决方案:
一、请求乱码问题(客户端 → 服务器)
1. GET 请求乱码
原因:URL 参数默认使用 ISO-8859-1 编码
解决方案:
// 方法1:修改 Tomcat 配置 (server.xml)
<Connector port="8080" URIEncoding="UTF-8" .../>// 方法2:代码转换
String param = request.getParameter("name");
param = new String(param.getBytes("ISO-8859-1"), "UTF-8");// 方法3:URL 重写时手动编码
String url = "?name=" + URLEncoder.encode("中文", "UTF-8");
2. POST 请求乱码
原因:请求体未正确设置编码
解决方案:
// 在获取参数前设置编码
request.setCharacterEncoding("UTF-8");// 若使用过滤器全局设置:
public class EncodingFilter implements Filter {public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {req.setCharacterEncoding("UTF-8");chain.doFilter(req, resp);}
}
3. AJAX 请求乱码
// 前端设置
$.ajax({url: "api",contentType: "application/x-www-form-urlencoded; charset=UTF-8",data: {name: "中文"}
});// 后端配合
request.setCharacterEncoding("UTF-8");
二、响应乱码问题(服务器 → 客户端)
1. 文本响应乱码
解决方案:
// 方法1:设置响应头 (必须最先执行)
response.setContentType("text/html;charset=UTF-8");// 方法2:双重设置 (兼容性最佳)
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");// 方法3:使用 PrintWriter 前设置
PrintWriter out = response.getWriter();
response.setContentType("text/html;charset=UTF-8"); // 错误!此时已失效
2. JSON 响应乱码
// Spring MVC 解决方案
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();converter.setDefaultCharset(StandardCharsets.UTF_8);converters.add(converter);}
}// 原生 Servlet
response.setContentType("application/json;charset=UTF-8");
String json = "{\"name\":\"张三\"}";
response.getWriter().write(json);
3. 文件下载乱码
// 文件名乱码解决
String fileName = "中文文件.txt";
String encodedName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); // 空格处理response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedName);
三、JSP 页面乱码
1. 页面本身乱码
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
2. EL 表达式乱码
<!-- web.xml 配置 -->
<jsp-config><jsp-property-group><url-pattern>*.jsp</url-pattern><page-encoding>UTF-8</page-encoding></jsp-property-group>
</jsp-config>
3. JSP 包含乱码
<%-- 在父页面设置 --%>
<%@ page contentType="text/html;charset=UTF-8" %><%-- 包含时指定编码 --%>
<jsp:include page="child.jsp" flush="true"><jsp:param name="param" value="<%= URLEncoder.encode("中文","UTF-8") %>"/>
</jsp:include>
四、数据库乱码问题
1. 连接字符串设置
// JDBC URL 添加参数
String url = "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8";
2. 数据库/表级别设置
CREATE DATABASE db DEFAULT CHARACTER SET utf8mb4;CREATE TABLE table (...
) DEFAULT CHARSET=utf8mb4;
五、综合解决方案框架
1. 过滤器配置 (web.xml)
<filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param>
</filter>
<filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
2. 服务器级配置
服务器 | 配置文件 | 关键配置项 |
---|---|---|
Tomcat | server.xml | <Connector URIEncoding="UTF-8"> |
Jetty | jetty.xml | <Set name="requestEncoding">UTF-8</Set> |
WebLogic | weblogic.xml | <charset-params> <input-charset> <resource-path>/*</resource-path> <java-charset-name>UTF-8</java-charset-name> </input-charset> </charset-params> |
六、乱码排查流程图
七、终极校验表
检查点 | 正确配置 | 常见错误值 |
---|---|---|
请求编码 | request.setCharacterEncoding(“UTF-8”) | 缺失或错误编码 |
响应Content-Type | text/html;charset=UTF-8 | 缺少charset |
JSP pageEncoding | <%@ page pageEncoding=“UTF-8”%> | 缺失或ISO-8859-1 |
数据库连接 | characterEncoding=UTF-8 | 缺失或错误编码 |
文件读取 | new InputStreamReader(fis, “UTF-8”) | 使用系统默认编码 |
操作系统编码 | UTF-8 | GBK 或其它本地化编码 |
黄金法则:
- 全程使用 UTF-8 编码
- 请求处理前设置编码
- 响应输出前设置 Content-Type
- 所有环节显式指定编码(不要依赖默认值)