json前后台传输,以及乱码中文问题探讨
背景介绍:
我现在的工作是做传统项目开发,没有用到框架。最近在做项目时,经常需要使用ajax从后台拿数据到前台,是json格式的。先说下我在项目中遇到的问题吧,前台拿到了数据,需要将其转化为对象,我使用的是jquery插件带有的jQuery.parseJSON() 这个方法,没有效果,使用浏览器自带的JSON.parse(str)也是没有效果,通过查阅才知道,这个方法对于对于ie浏览器的支持并不怎么好,目前支持的是ie8(非兼容模式),ie9,等以上的版本,做传统开发的应该知道,浏览器只能用ie,无奈通过查阅得知,要想使用这个方法,需要导入一个json.js,可以从github上下载,地址:https://github.com/douglascrockford/JSON-js ,将json2.js导入到你的项目里面就好了。我没有使用这种方法,我使用的是js的eval函数。使用方法:
function test3(){ var json = '{"name":"李四","age":"23"}'; var $json = eval("("+json+")"); alert(typeof($json));//object alert($json.name);//李四 }
上面的小例子演示eval怎么使用的。下面我们来看看对于ssm架构的项目怎么使用json数据格式传输的吧!
前提:掌握json对象和json字符串的互相转化;
json对象——》json字符串:
JSON.stringify(json对象);
json字符串-——》json对象
eval(“(”+json字符串+")")函数,$.parseJSON(json字符串),JQuery.parseJSON(json字符串),JSON.parse(json字符串);
对于json对象,取值,只需要.属性就可以了。
一、前台接受后台传输过来的json数据乱码问题
背景:使用ssm框架
后台:
1 @RequestMapping("/test1") 2 @ResponseBody 3 public ResultInfo test1(HttpServletResponse response){ 4 ResultInfo result = new ResultInfo(); 5 result.setCode("200"); 6 result.setDesc("请求成功!"); 7 Map<String,String> map = new HashMap<String,String>(); 8 map.put("name", "求成"); 9 map.put("age","35"); 10 result.setData(map); 11 return result; 12 }
前台:
1 function test1(){ 2 $.ajax({ 3 type:'post', 4 url:'json/test1', 5 datatype:'josn', 6 success:function(text){ 7 var code = text.code; 8 var desc = text.desc; 9 alert(code+desc); 10 var obj = text.data; 11 alert(obj.name + obj.age); 12 var str = JSON.stringify(text); 13 alert(str); 14 }, 15 error:function(data){ 16 alert("后台发生异常,请联系管理员!"); 17 }, 18 asyn:false, 19 cache:false 20 }); 21 }
此时没有乱码发生,但是有时我们前台接受的text的类型有时是json对象,有时是json类型的字符串,怎么准确的判别我们从后台拿到什么类型的数据呢?这里先不说,在下面说
看第二个例子
后台:
1 @RequestMapping(value="/test2"/*,produces="text/html;charset=UTF-8"*/) 2 @ResponseBody 3 public String test2(HttpServletResponse response){ 4 ResultInfo result = new ResultInfo(); 5 result.setCode("200"); 6 result.setDesc("请求成功!"); 7 Map<String,String> map = new HashMap<String,String>(); 8 map.put("name", "红霞"); 9 map.put("age","22"); 10 result.setData(map); 11 String str = JSONObject.toJSONString(result); 12 System.out.println(str); 13 return str; 14 }
前台:
1 function test2(){ 2 $.ajax({ 3 type:'post', 4 url:'json/test2', 5 datatype:'json', 6 success:function(text){ 7 alert(text); 8 alert(text.code+text.desc); 9 }, 10 error:function(text){ 11 alert("后台发生异常!"); 12 }, 13 asyn:false, 14 cache:false 15 }); 16 }
此时前台发生了乱码,就算是设置了response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8");
这两句话也是不起作用,如果这样设置: @RequestMapping(value="/test2",produces="text/html;charset=UTF-8") 此时是不乱码的。此时应该能够解决到所有人的遇到的中文乱码的问题!
其实归根结底来说都是消息转换器在作怪!!!
其实我们可以打开字符消息转换器来查看下。可以看出字符串转换器默认的编码式iso-8859-1
1 public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> { 2 3 public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1"); 4 5 6 private final List<Charset> availableCharsets; 7 8 private boolean writeAcceptCharset = true;
后台test1:走的是MappingJackson2HttpMessageConverter这个转换器,直接将对象传回到前台。
后台test2: 走的是StringHttpMessageConverter 这个转换器,然后将字符串用iso-8859-1编码。
自然就会出现乱码了。
我们可以通过自定义消息转换器的编码:如下
1 <mvc:annotation-driven > 2 <mvc:message-converters register-defaults="true"> 3 <bean class="org.springframework.http.converter.StringHttpMessageConverter" > 4 <property name = "supportedMediaTypes"> 5 <list> 6 <value>application/json;charset=utf-8</value> 7 <value>text/html;charset=utf-8</value> 10 </list> 11 </property> 12 </bean> 13 <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" > 14 </bean> 15 </mvc:message-converters> 16 </mvc:annotation-driven>
过程中,我发现个有意思的地方,对于test2(),如果把text/html放在前面,返回前台是string的json串,如果把application放在前面,返回到前台是json对象,其实不难理解,
在走StringHttpMessageConverter这个转换器的时候,会拿这个转换器里面的支持的数据类型和请求头可接受的数据类型比对,就是请求头里面的accept,如果比对成功,就不再比对下一个,所以这就可以拿捏的准前台拿到的数据是什么类型了。
总结下:
要想不乱码可有两种方法
第一:在注解@requestMapping()里面加上:produces="text/html;charset=UTF-8"
第二:在消息转换器里面配置上指定的编码。