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 = newResultInfo(); 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> 8 <!-- application 可以在任意 form 表單裏面 enctype 屬性默認找到 --> 9 <value>application/x-www-form-urlencoded</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"
第二:在消息轉換器裏面配置上指定的編碼。
json前後臺傳輸,以及亂碼中文問題探討