问题:
两套业务逻辑代码相同,但返回的数据不同,导致相同的前端代码用eval解析时出错。其中一个多了一层双引号,分别为
"{\"aaa\":1}" "\"{\"aaa\":1}\""
//服务端代码
@RequestMapping(method = , params = "method=xxx")
public
@ResponseBody
String xxx() {
Result r = ();
String result = (r);
return result;
}
//客户端代码
(url, data, function (result1) {
if (result1 != "" && result1 != null) {
var objs = eval('(' + result1 + ')');
var myResult = eval('(' + objs + ')');
}
})
解决思路:
- 比较服务端业务代码:一致,且断点调试return的字符串相同,都是"{\"aaa\":1}"
- 比较前端代码:一致,且前端引擎都是velocity
- 比较http协议:不一致,request头信息一致,但reponse头信息不一致,返回一层双引号的是 Content-Type:application/json;charset=UTF-8,返回两层双引号的是Content-type:text/html;charset=utf-8,于是怀疑有过滤器或拦截器修改了响应头信息
- 查看过滤器和拦截器:两边一致,并且都没有修改响应头信息
- 查看spring mvc的配置的json解析工具:都是jackson,但两个配置文件中supportedMediaTypes的顺序不一致,再考虑到响应头的不同,终于找到了问题的答案-Spring选择Converter是有优先级的(1、请求中的ContentType和Accept对应的Converter 2、如果1无法找到对应Converter,则通过遍历MessageConverters的canRead/canWrite选择最有可能的Converter 3、如果2无法找到对应Converter,则返回错误。)
//一层引号springmvc配置的json解析
<bean
class=".MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<ref bean="mappingJacksonHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
//两层引号springmvc配置的json解析
<bean
class=".MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="">
<property name="messageConverters">
<util:list >
<ref bean="mappingJacksonHttpMessageConverter"/>
</util:list>
</property>
</bean>
解决方案
- 修改spring mvc的配置文件,调整消息转换器的顺序
- 一层引号的版本,前端去掉一层eval函数
- 优化:
- 服务端的()是多余的,因为spring mvc配置的json解析工具会自动序列化结果。
- text/html;charset=UTF-8这种Content-Type会在数据外层包裹上一层双引号,如果返回的是string类型,则会出现两层双引号;返回Object,也会出现一层双引号,需要用eval来去除,或者在jQuery post() 方法指定预期的服务器响应的数据类型为'json';
//服务端代码
@RequestMapping(method = , params = "method=xxx")
public
@ResponseBody
Object xxx() {
Result r = ();
Return r;
}
//1、客户端代码(如果响应头是application/json;charset=UTF-8)
(url, data, function (result1) {
if (result1 != "" && result1 != null) {
var myResult = result1;
}
})
//2、1 客户端代码(如果响应头是text/html;charset=UTF-8)
(url, data, function (result1) {
if (result1 != "" && result1 != null) {
var myResult = result1;
}
},'json')
//2、2 客户端代码(如果响应头是text/html;charset=UTF-8)
(url, data, function (result1) {
if (result1 != "" && result1 != null) {
var myResult = eval('(' + result1+ ')');
}
})