解决spring3.0.5使用RestTemplate发送post请求响应中文乱码问题

说明:

     1:使用spring3.0.5 post响应编码类型,更加请求url响应内容的编码决定,请求的url没有设置响应编码,默认为ISO-8859-1



  2:  使用如下代码解析请求:

package com.spring.rest;


import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import ognl.ParseException;


import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;

import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;


import com.alibaba.fastjson.JSONObject;


public class RestTempLateClient {
/** 
     * 模拟请求 
     *  
     * @param url       资源地址 
     * @param map   参数列表 
     * @param encoding  编码 
     * @return 
     * @throws ParseException 
     * @throws IOException 
     */  
    public static String send(String url, Map<String,Object> map,String encoding) {  
    RestTemplate restTemplate = new RestTemplate();
    //3.1.X以上版本使用
    //restTemplate.getMessageConverters().add(0, StringHttpMessageConverter.DEFAULT_CHARSET);
   
    List<HttpMessageConverter<?>> converterList=restTemplate.getMessageConverters();
    HttpMessageConverter<?> converter = new StringHttpMessageConverter();
    converterList.add(0, converter);
    restTemplate.setMessageConverters(converterList);


    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
    headers.setContentType(type);
    headers.add("Accept", MediaType.APPLICATION_JSON.toString());
    //map 转换为json对象
    JSONObject jsonObj = new JSONObject(map);


    HttpEntity<String> formEntity = new HttpEntity<String>(jsonObj.toString(), headers);


    String result = restTemplate.postForObject(url, formEntity, String.class);
    return result;
    }  
    
    public static void main(String[] args) throws ParseException, IOException {  
        String url="http://php.weather.sina.com.cn/iframe/index/w_cl.php";  
        Map<String, Object> map = new HashMap<String, Object>();  
        map.put("code", "js");  
        map.put("day", "0");  
        map.put("city", "上海");  
        map.put("dfc", "1");  
        map.put("charset", "utf-8");  
        String body = send(url, map,"utf-8");  
        System.out.println("交易响应结果:");  
        System.out.println(body);  
  
        System.out.println("-----------------------------------");  
  
        map.put("city", "北京");  
        body = send(url, map, "utf-8");  
        System.out.println("交易响应结果:");  
        System.out.println(body);  
    }
}


请求结果如下:

log4j:WARN No appenders could be found for logger (org.springframework.web.client.RestTemplate).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
交易响应结果:
(function(){var w=[];w['¼ª°²']=[{s1:'ÕóÓê',s2:'ÕóÓê',f1:'zhenyu',f2:'zhenyu',t1:'28',t2:'23',p1:'¡Ü3',p2:'¡Ü3',d1:'ÄÏ·ç',d2:'ÄÏ·ç'}];var add={now:'2017-06-19 22:17:11',time:'1497881831',update:'±±¾©Ê±¼ä06ÔÂ18ÈÕ08:10¸üÐÂ',error:'0',total:'1'};window.SWther={w:w,add:add};})();//0


-----------------------------------
交易响应结果:
(function(){var w=[];w['¼ª°²']=[{s1:'ÕóÓê',s2:'ÕóÓê',f1:'zhenyu',f2:'zhenyu',t1:'28',t2:'23',p1:'¡Ü3',p2:'¡Ü3',d1:'ÄÏ·ç',d2:'ÄÏ·ç'}];var add={now:'2017-06-19 22:17:12',time:'1497881832',update:'±±¾©Ê±¼ä06ÔÂ18ÈÕ08:10¸üÐÂ',error:'0',total:'1'};window.SWther={w:w,add:add};})();//0


解决办法:

1:修改spring源码,将编码改为gbk; ----   是一个方法,感觉不太好


2:拷贝spring中的StringHttpMessageConverter类源码,做为一个单独的类,修改编码



package com.spring.rest;
/*
 * Copyright 2002-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */




import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;


import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.util.FileCopyUtils;


/**
 * Implementation of {@link HttpMessageConverter} that can read and write strings.
 *
 * <p>By default, this converter supports all media types (<code>&#42;&#47;&#42;</code>), and writes with a {@code
 * Content-Type} of {@code text/plain}. This can be overridden by setting the {@link
 * #setSupportedMediaTypes(java.util.List) supportedMediaTypes} property.
 *
 * @author Arjen Poutsma
 * @since 3.0
 */
public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {


public static final Charset DEFAULT_CHARSET = Charset.forName("gbk");


private final List<Charset> availableCharsets;


private boolean writeAcceptCharset = true;


public StringHttpMessageConverter() {
super(new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL);
this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
}


/**
* Indicates whether the {@code Accept-Charset} should be written to any outgoing request.
* <p>Default is {@code true}.
*/
public void setWriteAcceptCharset(boolean writeAcceptCharset) {
this.writeAcceptCharset = writeAcceptCharset;
}


@Override
public boolean supports(Class<?> clazz) {
return String.class.equals(clazz);
}


@Override
protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {
MediaType contentType = inputMessage.getHeaders().getContentType();
Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
}


@Override
protected Long getContentLength(String s, MediaType contentType) {
if (contentType != null && contentType.getCharSet() != null) {
Charset charset = contentType.getCharSet();
try {
return (long) s.getBytes(charset.name()).length;
}
catch (UnsupportedEncodingException ex) {
// should not occur
throw new InternalError(ex.getMessage());
}
}
else {
return null;
}
}


@Override
protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException {
if (writeAcceptCharset) {
outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
}
MediaType contentType = outputMessage.getHeaders().getContentType();
Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset));
}


/**
* Return the list of supported {@link Charset}.
*
* <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses.
*
* @return the list of accepted charsets
*/
protected List<Charset> getAcceptedCharsets() {
return this.availableCharsets;
}


}



package com.spring.rest;


import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import ognl.ParseException;


import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.client.RestTemplate;


import com.alibaba.fastjson.JSONObject;


public class RestTempLateClient {
/** 
     * 模拟请求 
     *  
     * @param url       资源地址 
     * @param map   参数列表 
     * @param encoding  编码 
     * @return 
     * @throws ParseException 
     * @throws IOException 
     */  
    public static String send(String url, Map<String,Object> map,String encoding) {  
    RestTemplate restTemplate = new RestTemplate();
    //3.1.X以上版本使用
    //restTemplate.getMessageConverters().add(0, StringHttpMessageConverter.DEFAULT_CHARSET);
   
    List<HttpMessageConverter<?>> converterList=restTemplate.getMessageConverters();
    HttpMessageConverter<?> converter = new StringHttpMessageConverter();
    converterList.add(0, converter);
    restTemplate.setMessageConverters(converterList);


    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
    headers.setContentType(type);
    headers.add("Accept", MediaType.APPLICATION_JSON.toString());
    //map 转换为json对象
    JSONObject jsonObj = new JSONObject(map);


    HttpEntity<String> formEntity = new HttpEntity<String>(jsonObj.toString(), headers);


    String result = restTemplate.postForObject(url, formEntity, String.class);
    return result;
    }  
    
    public static void main(String[] args) throws ParseException, IOException {  
        String url="http://php.weather.sina.com.cn/iframe/index/w_cl.php";  
        Map<String, Object> map = new HashMap<String, Object>();  
        map.put("code", "js");  
        map.put("day", "0");  
        map.put("city", "上海");  
        map.put("dfc", "1");  
        map.put("charset", "utf-8");  
        String body = send(url, map,"utf-8");  
        System.out.println("交易响应结果:");  
        System.out.println(body);  
  
        System.out.println("-----------------------------------");  
  
        map.put("city", "北京");  
        body = send(url, map, "utf-8");  
        System.out.println("交易响应结果:");  
        System.out.println(body);  
    }
}



响应结果:

log4j:WARN No appenders could be found for logger (org.springframework.web.client.RestTemplate).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
交易响应结果:
(function(){var w=[];w['深圳']=[{s1:'大雨',s2:'中到大雨',f1:'dayu',f2:'zhongyu',t1:'30',t2:'26',p1:'≤3',p2:'≤3',d1:'无持续风向',d2:'无持续风向'}];var add={now:'2017-06-19 22:18:49',time:'1497881929',update:'北京时间06月18日08:10更新',error:'0',total:'1'};window.SWther={w:w,add:add};})();//0


-----------------------------------
交易响应结果:
(function(){var w=[];w['深圳']=[{s1:'大雨',s2:'中到大雨',f1:'dayu',f2:'zhongyu',t1:'30',t2:'26',p1:'≤3',p2:'≤3',d1:'无持续风向',d2:'无持续风向'}];var add={now:'2017-06-19 22:18:50',time:'1497881930',update:'北京时间06月18日08:10更新',error:'0',total:'1'};window.SWther={w:w,add:add};})();//0


猜你喜欢

转载自blog.csdn.net/kinbridge/article/details/73477731