@GetMapping("/{id}") @ResponseBody XXDto findById(@PathVariable String id) { return service.findById(id); // 此处如果返回 null,相应的转换没有做 }
@Configuration public class HttpMessageConverter { @Bean public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { return new MappingJackson2HttpMessageConverter() { @Override protected void writePrefix(JsonGenerator generator, Object object) throws IOException { if (object instanceof ArrayList) { List list = (List) object; if (!list.isEmpty()) { if (list.get(0) instanceof SwaggerResource) { super.writePrefix(generator, object); return; } } } if (object instanceof Json || object instanceof SecurityConfiguration || object instanceof UiConfiguration) { super.writePrefix(generator, object); return; } generator.writeRaw("{\"code\": 0, \"result\": "); super.writePrefix(generator, object); } @Override protected void writeSuffix(JsonGenerator generator, Object object) throws IOException { if (object instanceof ArrayList) { List list = (List) object; if (!list.isEmpty()) { if (list.get(0) instanceof SwaggerResource) { super.writeSuffix(generator, object); return; } } } if (object instanceof Json || object instanceof SecurityConfiguration || object instanceof UiConfiguration) { super.writeSuffix(generator, object); return; } generator.writeRaw("}"); super.writeSuffix(generator, object); } }; } }
当上述 1 中方法返回 null 时,2 中的 writePrefix 和 writeSuffix 不会被调到?有什么办法解决这个问题吗?
![]() | 1 letitbesqzr 2018-05-04 21:27:28 +08:00 Spring mvc 在 RequestResponseBodyMethodProcesser 会检测返回结果是不是 null , 如果不为 null 才会走 HttpMessageConverter 去处理。 |
![]() | 2 letitbesqzr 2018-05-04 21:35:42 +08:00 纠错,是 org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor 如果确实要返回的 null 走你自己的 HttpMessageConverter, 建议自己去覆盖 RequestResponseBodyMethodProcessor 以接受 null。 或者自己定义一个 annotation @ResponseBodyNull 创建一个对应的 HandlerMethodReturnValueHandler |
3 aa6563679 2018-05-05 00:05:23 +08:00 via iPhone 我记得在 spring mvc 里如果要手动处理 HttpServletResponse 就需要返回 null 或 void |
4 FreeBSD OP @letitbesqzr 感谢。看来只能手撸了。我之前还想过 AOP 的招 |
5 /div> FreeBSD OP 按照[Custom HttpMessageConverter in Spring MVC]( https://stackoverflow.com/questions/22890952/custom-httpmessageconverter-in-spring-mvc) 没有成功 |
![]() | 6 BBCCBB 2018-05-05 18:22:43 +08:00 建议你外面套一层 ```java class Response<T> { int code; String msg; T value; } ``` 然后返回一个 Response<XXDto> |
![]() | 8 BBCCBB 2018-05-05 20:11:50 +08:00 @FreeBSD 额,这个方法绝壁不土,我待过的公司都是这种套路,因为你失败的时候可以返回具体的 code 和失败原因 msg,也便于前台展示 |
9 FreeBSD OP @letitbesqzr 按照#5 楼链接的实现,发现还是有问题。转换时并没调用自定义的 RequestResponseBodyMethodProcessor 中的 handleReturnValue 方法。能再给点建议吗? |
10 cqy2016 2018-05-06 14:59:50 +08:00 ![]() 想在方法上省掉 wrapper 的话,扩展不应该用 message convert 提供一个 ResponseBodyAdvice 就行了 |
![]() | 11 james2013 2018-05-16 17:59:34 +08:00 ![]() 以前也是用 BBCCBB 的方法,cqy2016 说的很好,试了下,完美解决楼主的问题,并且做了其它几个方面的适配: @ControllerAdvice public class MyResponseBodyAdvice implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { if("org.springframework.http.converter.json.MappingJackson2HttpMessageConverter".equals(converterType.getName())){ return true; } return false; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if(body instanceof BaseResponseBean) return body; return ResponseUtil.turnData(body); } } |