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 map = parseMapWithUserId(parameters);
logger.info("get methodName:" + methodName + ",url:" + routerUrl);
responseEntity = restTemplate.getForEntity(routerUrl,String.class,map);
返回200,这个没问题,重点是:访问Restfull接口竟然返回的是XML格式的数据!!!而且中文还是乱码。
其实对于中文乱码的问题我倒是预料到了,在restTemplate的MessageConverters集合里加入StringHttpMessageConverter就可以了,代码如下:
RestTemplate restTemplate =new RestTemplate();
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
乱码问题解决
这个问题比较怪异,我的项目中有五个组件,都是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的问题一并解决了,效果如下:
完美