记录一次springAop引发的惨案
一、问题场景
因为项目中的id是long类型,在controller返回前端的时候会失真(js的类型和java不一致,不知道的百度)
//需要的结果
{
"errorCode": 0,
"msg": "处理成功",
"data": {
"AA": [ {
"id": "1564127421015329420",
"code": "ecf687fcc1438f18ae14c20f288aa386c681f37995c24fdc9457c9b3666d578f",
}
]
}
}
二、解决
因此在实体类上的id字段加上了@JsonSerialize(using= ToStringSerializer.class)注解
这个是spring默认的转换json的工具,jackson提供的
但是在加了注解之后发现有的方法有效,有的方法没有效果,现在给出解决办法一
public void save(HttpServletResponse response, @RequestBody XXX xxx) throws Exception {
//token校验
User user = checkToken(xxx.getToken());
ApiResult result = xxxService.save(xxx);
//return result;
//直接利用response的getWriter获得输出流,向外输出,就是页面
ObjectMapper objectMapper = new ObjectMapper();
String bbb = objectMapper.writeValueAsString(result);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().print(bbb);
//ResponseUtils.writeContent(response,bbb);
}
上述方法虽能解决,总觉得不够优雅,搂着跟踪源码,找到输出的代码
//这个代码在 org.springframework.http.converter.AbstractGenericHttpMessageConverter里面
public final void write(final T t, @Nullable final Type type, @Nullable MediaType contentType,
HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
final HttpHeaders headers = outputMessage.getHeaders();
addDefaultHeaders(headers, t, contentType);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(outputStream -> writeInternal(t, type, new HttpOutputMessage() {
@Override
public OutputStream getBody() {
return outputStream;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}));
}
else {
writeInternal(t, type, outputMessage);//这一步就是进行json转换的
outputMessage.getBody().flush();//这一步直接输出
}
}
这里分享一下如何查看结果是否被转化为json
这个是进入write方法的返回对象,里面的id还是Long类型,接着到最后一步
用idea的可以在断点里面打开计算
点击红点,打开计算输入公式,看到输出流,就是一堆数字,直接右键,view as string 就能看到字符串结果。
回归正题,其实我的问题并不是有没有转化,而是发现这个方法根本没有进入断点,找了半天终于发现这个controller上面加了aop的注解,aop的注解使用的是around方法,但是没有返回值,而是直接输出在页面
HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();
ResponseUtils.writeJson(response, result);
//return result;
其实发现只用将aop的返回结果改为Object,在最后返回result即可。
aop的配置就不贴出来了,这里提供了一种解决long类型的数据失真解决方法
三、结束
问题解决,记录于此!
本文为原创文章转载请注明出处。
aop的如有疑问请留言。