1. 程式人生 > >RestTemplate踩坑筆記-中文亂碼與json被解析成xml

RestTemplate踩坑筆記-中文亂碼與json被解析成xml

1.RestTemplate訪問Restfull介面:中文亂碼+返回資料格式為xml

Spring Cloud專案,肯定會用到元件之間的Http通訊,我使用的是spring提供的簡單便捷的模板類:RestTemplate。

Restfull介面如下:

@RestController
@RequestMapping("/logonLog")
public class LogonLogController {
    private Logger logger = LoggerFactory.getLogger(LogonLogController.class);

    @Resource
    private LogonLogService logonLogService;

    @RouterAttribute(id = MyLogRouter.GET_LOGON_LOG_BY_PAGE ,description = "分頁查詢登入日誌")
    @RequestMapping(value = "/getPageList",method = RequestMethod.GET)
    public ResponseEntity getPageList(Integer currentPage,Integer pageSize){
        if(currentPage == null || pageSize == null){
            return MyResponse.badRequest();
        }
        return ResponseEntity.ok(logonLogService.getPageList(currentPage,pageSize));
    }
}

請求:restTemplate.getForEntity(routerUrl,String.class,map);

String urlParameters = getUrlParametersWithUserId(parameters);
                    routerUrl += urlParameters;
                    //請求引數
                    Map<String,Object> map = parseMapWithUserId(parameters);
                    logger.info("get  methodName:" + methodName + ",url:" + routerUrl);
                    responseEntity = restTemplate.getForEntity(routerUrl,String.class,map);

返回200,這個沒問題,重點是:訪問Restfull介面竟然返回的是XML格式的資料!!!而且中文還是亂碼。

2.解決中文亂碼

其實對於中文亂碼的問題我倒是預料到了,在restTemplate的MessageConverters集合里加入StringHttpMessageConverter就可以了,程式碼如下:

RestTemplate restTemplate =new RestTemplate();
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));

亂碼問題解決

3.解決返回XML問題

這個問題比較怪異,我的專案中有五個元件,都是Restfull介面,但訪問一部分元件返回的是正常的json,一部分元件返回的是xml。分別對每個元件使用postman直接訪問,返回的都是正常的json。那麼不出意外,應該就是RestTemplate在搗鬼了。

二話不說,直接扒原始碼,發現了一個可疑的傢伙:jackson2XmlPresent

public RestTemplate() {
	this.messageConverters.add(new ByteArrayHttpMessageConverter());
	this.messageConverters.add(new StringHttpMessageConverter());
	this.messageConverters.add(new ResourceHttpMessageConverter(false));
	this.messageConverters.add(new SourceHttpMessageConverter<>());
	this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
	if (romePresent) {
		this.messageConverters.add(new AtomFeedHttpMessageConverter());
		this.messageConverters.add(new RssChannelHttpMessageConverter());
	}
	if (jackson2XmlPresent) {
		this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
	}
	else if (jaxb2Present) {
		this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
	}
        if (jackson2Present) {
		this.messageConverters.add(new MappingJackson2HttpMessageConverter());
	}
	else if (gsonPresent) {
		this.messageConverters.add(new GsonHttpMessageConverter());
	}
	else if (jsonbPresent) {
		this.messageConverters.add(new JsonbHttpMessageConverter());
	}
	if (jackson2SmilePresent) {
		this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
	}
	if (jackson2CborPresent) {
		this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
	}
}

原來在RestTemplate的messageConverters中有這麼多成員常駐著,別的我不管,這個jackson2XmlPresent可是要了命的鬼啊,雖然我沒直接證據證明是它把我的json轉成Xml,但看著它就來氣,果斷弄掉。

等等,我在專案中用到的是FastJson,RestTemplate的messageConverters裡面沒有FastJson,作為一個處女座程式設計師,怎麼能容許你用jackson解析我的FastJson呢,果斷幹掉jackson,加入FastJson,程式碼如下:

RestTemplate restTemplate =new RestTemplate();
restTemplate.getMessageConverters().clear();
restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter());

幹掉所有messageConverters,加入FastJsonHttpMessageConverter,由於FastJsonHttpMessageConverter預設字符集就是UTF8,因此,一行程式碼將中文亂碼和json解析成xml的問題一併解決了,效果如下:

 

完美