Spring Boot 如果 RestController 中返回 null,则不会走进自定义 MappingJackson2HttpMessageConverter? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
FreeBSD
V2EX    Java

Spring Boot 如果 RestController 中返回 null,则不会走进自定义 MappingJackson2HttpMessageConverter?

  •  
  •   FreeBSD 2018-05-04 18:28:12 +08:00 7909 次点击
    这是一个创建于 2717 天前的主题,其中的信息可能已经有所发展或是发生改变。
    h2>1. RestController 的代码
     @GetMapping("/{id}") @ResponseBody XXDto findById(@PathVariable String id) { return service.findById(id); // 此处如果返回 null,相应的转换没有做 } 

    2. 代码 MappingJackson2HttpMessageConverter

    @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); } }; } } 

    3. 问题

    当上述 1 中方法返回 null 时,2 中的 writePrefix 和 writeSuffix 不会被调到?有什么办法解决这个问题吗?

    11 条回复    2018-05-16 17:59:34 +08:00
    letitbesqzr
        1
    letitbesqzr  
       2018-05-04 21:27:28 +08:00
    Spring mvc 在 RequestResponseBodyMethodProcesser 会检测返回结果是不是 null , 如果不为 null 才会走 HttpMessageConverter 去处理。
    letitbesqzr
        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
    aa6563679
        3
    aa6563679  
       2018-05-05 00:05:23 +08:00 via iPhone
    我记得在 spring mvc 里如果要手动处理 HttpServletResponse 就需要返回 null 或 void
    FreeBSD
        4
    FreeBSD  
    OP
       2018-05-05 11:10:55 +08:00
    @letitbesqzr 感谢。看来只能手撸了。我之前还想过 AOP 的招
    FreeBSD
        5
    /div> FreeBSD  
    OP
       2018-05-05 16:53:36 +08:00
    按照[Custom HttpMessageConverter in Spring MVC]( https://stackoverflow.com/questions/22890952/custom-httpmessageconverter-in-spring-mvc) 没有成功
    BBCCBB
        6
    BBCCBB  
       2018-05-05 18:22:43 +08:00
    建议你外面套一层
    ```java
    class Response<T> {
    int code;
    String msg;
    T value;
    }
    ```
    然后返回一个 Response<XXDto>
    FreeBSD
        7
    FreeBSD  
    OP
       2018-05-05 19:55:08 +08:00 via Android
    @BBCCBB 嗯,是个方法,但是比较土啊
    BBCCBB
        8
    BBCCBB  
       2018-05-05 20:11:50 +08:00
    @FreeBSD 额,这个方法绝壁不土,我待过的公司都是这种套路,因为你失败的时候可以返回具体的 code 和失败原因 msg,也便于前台展示
    FreeBSD
        9
    FreeBSD  
    OP
       2018-05-05 21:49:42 +08:00
    @letitbesqzr 按照#5 楼链接的实现,发现还是有问题。转换时并没调用自定义的 RequestResponseBodyMethodProcessor 中的 handleReturnValue 方法。能再给点建议吗?
    cqy2016
        10
    cqy2016  
       2018-05-06 14:59:50 +08:00   1
    想在方法上省掉 wrapper 的话,扩展不应该用 message convert
    提供一个 ResponseBodyAdvice 就行了
    james2013
        11
    james2013  
       2018-05-16 17:59:34 +08:00   1
    以前也是用 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);
    }
    }
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2750 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 09:12 PVG 17:12 LAX 02:12 JFK 05:12
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86