87.ajax提交 後臺返回中文亂碼問題
阿新 • • 發佈:2019-02-05
介面返回資料相關
使用@ResponseBody後返回NUll
說明:剛把後臺執行起來,興高采烈的測試介面資料,結果無論如何都是返回null, 最終通過各種百度,發現原來是沒有引入關鍵的Jar包. 解決辦法: 需要引入jackson的jar包(jackson core和jackson mapper),引入後 圖:使用@RequestMapping返回中文亂碼
原因分析:(網上基本都是一致的答案)
首先: 確定的是(經過多次測試的結果)只有當返回值是 String時才會出現中文亂碼,而當返回值是Map<String, Object>或者是其它型別時,並沒有中文亂碼的出現.
-
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
解決辦法(以及是否嘗試成功): 嘗試了很多種網上的辦法,有一些根本無用,有一些當客戶端的Accep是 application/json;時無用.最終也是結合客戶端的修改才成功解決問題的。 環境: SpringMvc 3.1 客戶端分為三種不同的請求: 1.瀏覽器中直接Get訪問,Accept是"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" 2.用Jquery的jsonp ajax請求,Accept是"*/*" 3.用h5+環境下的mui ajax請求,Accept是"application/json;charset=utf-8" (PS:h5+是最近做的跨平臺移動專案的開發環境,另外就是有試過預設的Accept"application/json"的話不管伺服器端用哪種方法,在呢麼配置,都會返回亂碼,所以最後只得手動加上charset=utf-8了) 注:
嘗試方法一: 在配置檔案中的mvc:annotation-driven中新增如下程式碼
- <mvc:annotation-driven >
- <!-- 訊息轉換器 -->
- <mvc:message-converters register-defaults="true">
- <bean class="org.springframework.http.converter.StringHttpMessageConverter">
- <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
- </bean>
- </mvc:message-converters>
- </mvc:annotation-driven>
嘗試方法二: 在配置檔案中的mvc:annotation-driven中新增如下程式碼
- <mvc:annotation-driven>
- <mvc:message-converters>
- <bean class="org.springframework.http.converter.StringHttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- <span style="white-space:pre"> </span> <value>text/html;charset=UTF-8</value>
- <value>application/json;charset=UTF-8</value>
- <value>*/*;charset=UTF-8</value>
- </list>
- </property>
- </bean>
- </mvc:message-converters>
- </mvc:annotation-driven>
嘗試方法三: 在@RequestMapping裡的配置produces="text/html;charset=UTF-8;"
- @RequestMapping(value = "***",produces="text/html;charset=UTF-8;")
原理: 手動給對應的Accept返回制定格式編碼資料。 最終結果: 請求方法1返回正確的中文 請求方法2返回正確的中文 請求方法3無法請求,出了錯,因為produces沒有新增application/json;對應的頭部.
嘗試方法四: 在@RequestMapping裡的併發配置produces={"application/json;","text/html;charset=UTF-8;"}
- @RequestMapping(value = "***",produces={"application/json;","text/html;charset=UTF-8;"})
原理: 手動給對應的Accept返回制定格式編碼資料。 最終結果: 請求方法1返回中文亂碼 請求方法2返回中文亂碼 請求方法3返回正確的中文
嘗試方法五: 在@RequestMapping裡的併發配置produces={"text/html;charset=UTF-8;","application/json;"}
- @RequestMapping(value = "***",produces={"text/html;charset=UTF-8;","application/json;"})
注意: 這裡和上個方法的區別是,produces裡面的順序對調了 原理: 手動給對應的Accept返回制定格式編碼資料。 最終結果: 請求方法1返回正確的中文 請求方法2返回正確的中文 請求方法3返回正確的中文 方法四和方法五對比分析: 發現produces設定多個Accept只有第一個的charset是有用的, 後面的Accept設定有效(因為不設定就無法接收對應的Accept請求),但是charset設定是無效的.需要客戶端手動制定charset才行. 具體原因並不清楚(原諒我並不精通) 所以得出的結論是:
produces={"text/html;charset=UTF-8;","application/json;"}
這樣設定,這樣普通瀏覽器的請求就能正常顯示中文,而客戶端的模擬請求(可以是ajax或http)則手動指定Accept的charset,即可正常接收中文。客戶端使用Ajax請求跨域問題
說明:剛剛搭建的Java web後臺程式,用Http請求很正常,但是用普通的ajax請求時,出現了一個跨域問題,被拒絕訪問. 解決辦法: 在.net後臺佈置在IIS伺服器上的,直接可以在IIS的應用池中配置Access-Control-Allow-Origin: *就行了. PhP後臺也只需要手動配置 header('Access-Control-Allow-Origin: *');header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept'); Java Web後臺可以再對應的tomcat伺服器上通過CORS配置跨域訪問(詳情見另一篇),這裡暫時只探討Java Web的JSONP實現 於是: 這裡的Java Web後臺採用了JSONP傳輸方式來支援跨域. (缺點就是隻支援Get,而且需要伺服器端有JSONP的判斷,因為返回引數和普通的不一樣) JSONP前端程式碼:(這裡是用了JQ的jsonp請求)
- <span style="white-space:pre"> </span>$.ajax(url, {
- data: data,
- dataType: "jsonp",
- jsonpCallback: 'testGetData',
- timeout: "15000", //超時時間設定為3秒;
- type: "POST",
- success: function(response) {
- var result = 'success:' + JSON.stringify(response);
- //返回的是utf8編碼,需要手動轉為utf16
- console.log(result);
- //alert(result);
- },
- error: function(error) {
- var result = 'error:' + JSON.stringify(error);
- console.log(result);
- //alert(result);
- }
- });
JSONP傳遞Java Web後臺程式碼片段: 1.在方法的最開頭獲取是否是JSONP請求-通過獲取callback引數
- //判斷是否是jsonp請求
- String jsoncallback = request.getParameter("callback");
- public static String getJsonPData(String callbackName,Map<String, Object> data) throws JsonGenerationException, JsonMappingException, IOException{
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(data);
- System.out.println("jsonp回撥:"+callbackName);
- System.out.println("jackson解析的字串:"+json);
- String result = "";
- if(callbackName==null||callbackName==""){
- //普通請求
- result = json;
- }else{
- //jsonp請求,返回的格式是類似於一個函式的字串形式(前端再執行這個回撥來獲取資料)
- result = callbackName+"("+json+")";
- }
- System.out.println("最終結果:"+result);
- return result;
- }