Struts框架下Ajax发送中文乱码问题的解决

Gavin [Web技术]

2008.11.15

在使用AJAX向服务器端发送中文数据时,出现乱码,折腾了很久,在网上也找了很多解决办法,比如全站UTF-8编码、请求头编码为中文、使用 javascript中的escape函数等等,但一一试过均无效。在绝望之际,找到了一篇和我的情况比较相近的文章(详见:http: //blog.csdn.net/wallimn/archive/2006/11/12/1380106.aspx),在详细参考这篇文章的做法之后终于把问题解决。

现在,把自己的解决方法写出来,以便有需要的朋友不要再像我那样走弯路。

环境:WinXP + Eclipse,JSP + Struts,页面用JavaScript结合Ajax控制,页面和服务器都使用UTF-8编码。

MyActionForm的属性:

1
2
3
4
5
private String nameEn = null;
 
private String nameSc = null;
 
private String nameTc = null;

Action(MyAction) 的excute方法里面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
MyActionForm maForm = (MyActionForm)form;
 
// must decoding, or else it will disorderly code
 
// 第二个设编码参数一定要设
 
String strNameEn = java.net.URLDecoder.decode(maForm.getNameEn(), "UTF-8");
 
String strNameSc = java.net.URLDecoder.decode(maForm.getNameSc(), "UTF-8");
 
String strNameTc = java.net.URLDecoder.decode(maForm.getNameTc(), "UTF-8");
 
System.out.println("strNameEn: " + strNameEn);
 
System.out.println("strNameSc: " + strNameSc);
 
System.out.println("strNameTc: " + strNameTc);

客户端代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<html>
 
<head>
 
<title>Test Ajax Send Chinese</title>
 
<script language="javascript">
 
<!--
 
var req;
 
function retrieveURL(url)
 
{
 
if(window.XMLHttpRequest){ // Non-IE browsers
 
req = new XMLHttpRequest();
 
}else if (window.ActiveXObject) { // IE browsers
 
req = new ActiveXObject("Microsoft.XMLHTTP");
 
}
 
if(req){
 
req.onreadystatechange = callback;
 
try {
 
req.open("POST", url, true);
 
req.setRequestHeader("CONTENT-TYPE", "application/x-www-form-urlencoded");
 
} catch (e) {
 
alert(e);
 
}
 
req.send(null);
 
}
 
}
 
function callback()
 
{
 
if (req.readyState == 4) { // Complete
 
if (req.status == 200) { // OK response
 
processMessage();
 
} else {
 
alert("Problem: " + req.statusText);
 
}
 
}
 
}
 
function processMessage()
 
{
 
alert('Test OK!');
 
}
 
function trim(srcString)
 
{
 
return srcString.replace(/^\s*/,'').replace(/\s*$/,'');
 
}
 
/*该函数就是测试函数,jsp表单上提供strNameEn、strNameSc、strNameTc三项内容*/
 
function test()
 
{
 
if(trim(document.MyActionForm.nameEn.value)==''||
 
trim(document.MyActionForm.nameSc.value)==''||
 
trim(document.MyActionForm.nameTc.value)=='')
 
{
 
alert('NO INPUT!');
 
return;
 
}
 
var url = 'MyAction.do';
 
url += '&nameEn=' + document.MyActionForm.nameEn.value +
 
'&nameSc=' + document.MyActionForm.nameSc.value +
 
'&nameTc=' + document.MyActionForm.nameTc.value;
 
url = encodeURI(encodeURI(url)); //这里一定要执行两次encodeURI,否则Action端会提示NULL
 
retrieveURL(url);
 
}
 
//-->
 
</script>
 
</head>
 
<body>
 
<h2>Test Ajax Send Chinese</h2>
 
<hr>
 
<html:form action="MyAction.do">
 
<table>
 
<tr><td>Name(English) </td><td><input type="text" name="nameEn"/></td></tr>
 
<tr><td>Name(Simplified Chinese) </td><td><input type="text" name="nameSc"/></td></tr>
 
<tr><td>Name(Traditional Chinese) </td><td><input type="text" name="nameTc"/></td></tr>
 
<tr><td align="right"><p><input type="button" name="btnSubmit" value="Test" onclick="test();"/></td><td>&nbsp;</td></tr>
 
</table>
 
<html:form>
 
</body>
 
</html>

注:

1、上面的MyAction对应你的Action,MyActionForm对应你的ActionForm

2、该方法对用“GET”(上面例子用“POST”)方法发送也有效,即javascript函数retrieveURL里面的语句:

 查看代码 JAVASCRIPT
1
req.open("POST", url, true);

改成

 查看代码 JAVASCRIPT
1
req.open("GET", url, true);

也行

3、关键地方在于编码:

 查看代码 JAVASCRIPT
1
url = encodeURI(encodeURI(url));

和解码:

1
2
3
4
5
String strNameEn = java.net.URLDecoder.decode(maForm.nameEn(), "UTF-8");
 
String strNameSc = java.net.URLDecoder.decode(maForm.nameSc(), "UTF-8");
 
String strNameTc = java.net.URLDecoder.decode(maForm.nameTc(), "UTF-8");

后记:

从后来的实践中发现,事实上这种情况不止存在于Ajax发送url到servlet,几乎所有的从Web client 发送url数据到Web server情况,也都存在这种问题,解决方法都可以类似或者相同。也就是说,这中情况实质上是Web client通过网络和Web Server之间的通信而引起的。


评论

输入后可按 Ctrl+Enter 提交评论.