Java Web 開發中,表單提交中文亂碼是困擾眾多開發者的經典問題。本文系統梳理亂碼產生根因,提供從前端頁面到後端 Servlet、配置文件的全鏈路解決方案。
計算機以二進制存儲文本,字符到二進制為編碼,二進制到字符為解碼。若編碼與解碼使用的碼表不一致,即產生亂碼。統一全鏈路編碼即可根治。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>Servlet 演示</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>中文亂碼測試</h2>
<form action="/servletDemo_1/encode" method="post">
姓名:<input type="text" name="name"/><br/>
密碼:<input type="password" name="pwd"/><br/>
<input type="submit" value="登入"/>
</form>
</body>
</html>
關鍵點:request.setCharacterEncoding("utf-8") 必須在獲取參數之前調用,且僅對 POST 請求有效。
public class ServletEncoding implements Servlet {
private String charSet = null;
@Override
public void init(ServletConfig config) throws ServletException {
charSet = config.getInitParameter("char");
System.out.println("編碼:" + charSet);
}
@Override
public void service(ServletRequest req, ServletResponse resp)
throws ServletException, IOException {
// 方案 3: 直接設置(僅 POST 有效)
// req.setCharacterEncoding("utf-8");
// 方案 4: 從 web.xml 讀取配置(推薦)
req.setCharacterEncoding(charSet);
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
System.out.println("name:" + name + ",pwd:" + pwd);
// 回應端同樣設置編碼
resp.setContentType("text/html;charset=utf-8");
String str = "<html><body><font color='red'>name:" + name + ",pwd:" + pwd + "</font></body></html>";
resp.getWriter().println(str);
}
// ... 其他方法省略
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" ...>
<servlet>
<servlet-name>encode</servlet-name>
<servlet-class>cn.hncu.servlet_2.ServletEncoding</servlet-class>
<init-param>
<param-name>char</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>encode</servlet-name>
<url-pattern>/encode</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
GET 參數在 URL 中,不受 setCharacterEncoding 影響。可用手動轉碼:
String gender = new String(req.getParameter("gender").getBytes("iso-8859-1"), "utf-8");
或配置 Filter 統一處理所有請求。
全鏈路統一使用 UTF-8:頁面編碼、請求解碼、回應編碼、資料庫連接、JVM 文件編碼。一處不一致,即可能亂碼。