最近遇到了一个很痛苦的问题,自己的项目(Struts2+Hibernate+Spring3),出现了这样的情况:
我在csdn论坛上提过问却没有人回答,地址为http://bbs.youkuaiyun.com/topics/391546445
下面是出问题的js代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
function
submitReply(flag){
var
content = editor.getContent();
//从一个插件(Editor)获取到用户输入内容
var
contentLength = editor.getContentLength(
false
);
if
(contentLength > 2000){
alert(
"输入的字符数太大,请重新输入!"
);
}
else
if
(contentLength != 0)
//判断内容是否为空
{
$.ajax({
type:
'POST'
,
url:
'subReply.action'
,
//调用了CommentAction.java的execcute()方法
data: {flag:flag,content:content},
dataType:
'json'
,
success:
function
(data){
$(
"#reply_"
+flag).val(
""
);
loadAnswerAndComment();
//刷新加载部分页面的方法,无影响
alert(
"提交成功!"
);
}
});
}
else
{
alert(
"回答内容不能为空!"
);
}
}
|
然后通过上面的url访问后台,后台是这样配置的:
首先上Struts2的配置:
1
2
|
<!-- ajax请求 -->
<action name="subReply" class="CommentAction" method="execute"></action>
|
然后是spring的配置:
1
2
3
4
|
<
bean
id
=
"CommentAction"
class
=
"com.stusys.action.qasystem.CommentAction"
>
<
property
name
=
"commentService"
ref
=
"CommentService"
></
property
>
<
property
name
=
"showQuestionService"
ref
=
"ShowQuestionService"
></
property
>
</
bean
>
|
意图是调用CommentAction类里面的execute方法。因为项目较大配置文件与源代码过长就不都放上来了只放了关键的。
这个项目在自己电脑的myeclipse编译后放在自己的电脑的tomcat上运行是没有问题的(win7,myeclipse8.6,tomcat-7.0.55),然后放上远程服务器(win 2003,tomcat-7.0.39),就出问题了,每次到这里请求就被服务器挂起,状态显示Aborted,控制台没有报错,firebug也没有,后来发现是根本还没有访问到那个action,服务器还没有响应就没了,状态码为0。发现data如果只有一个参数就能够进去,但我后台方法需要两个参数所以报了空指针。
这是Opera的截图:
这个问题困扰了好几天都无法解决,暑假就这样无端端浪费近十天,最后只能暂时放下,等到开学回到学校,找了工作室的师兄现场一起调,在这个过程中师兄发现了一个编码问题,因为上面参数content的值是从一个前端编辑器插件UEditor获取用户输入信息的·,这个值里面包含了这个插件指定的格式:<p>content from User</p>.这里面包含了jQuery ajax的非法字符,所以在访问后台Action的时候请求就直接被挂起。
解决方法是:
在页面上先用两次encodeURIComponent方法对参数content进行编码,因为传进去之后会解码,但结果并不是我们想要的,所以多编码一次来抵消掉这次解码,如下:
<span style="white-space:pre"> </span>function submitReply(flag){
//回答,追问,适用
var content = editor.getContent();
<span style="white-space:pre"> </span>//编码
alert(content);
content = encodeURIComponent(encodeURIComponent(content));
var contentLength = editor.getContentLength(false);
if(contentLength > 2000){
alert("输入的字符数太大,请重新输入!");
}
else if (contentLength != 0) //判断内容是否为空
{
$.ajax({
type: 'POST',
url:'subReply.action', //调用了CommentAction.java的execcute()方法
data: {flag:flag,content:content},
async: false,
dataType: 'json',
success:function(data){
$("#reply_"+flag).val("");
loadAnswerAndComment();
alert("提交成功!");
}
});
}
else{
alert("回答内容不能为空!");
}
}
然后在后台进行解码,解码也需要两次,因为第一次解码的结果还
是
“%3Cp%3E%E6%B5%8B%E8%AF%95%E5%93%88%3C%2Fp%3E”的形式,这段代码的意思是“<p>测试</p>”
解码的代码如下:
<span style="white-space:pre"> </span>System.out.println("未转码:" + content);
String str = URLDecoder.decode(content,"UTF-8");
content = URLDecoder.decode(str,"UTF-8");
System.out.println("转码:" + content);
URLDecoder来自java.net包。
这样就解决了问题了,但是最根本的原因,为什么在本地tomcat上运行的程序没问题,但在学校的服务器就不行,感觉应该是tomcat版本或者配置的问题,试着在tomcat的server.xml的Connect标签上面加上URIEncoding="UTF-8"属性也没用,而且我的tomcat配置与学校服务器的配置是一样的啊?(sercer.xml一样)
这个问题会继续深入去了解它。不过也算解决了jQuery Ajax访问后台Action请求被Aborted的问题了。