V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Amber2011
V2EX  ›  Java

Spring 有什么方式可以在不同方法中更改 @RequestResponseBody 中同一个 entity 的序列化方式

  •  
  •   Amber2011 · 2023-03-02 22:51:52 +08:00 · 1315 次点击
    这是一个创建于 630 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有个需求需要先请求 A 接口,再拿 A 接口的结果请求 B 接口

    A 接口的结果和 B 接口的请求体实际上是一样的,但是 json 序列化的方式不同

    A 接口 {name:'xxx',code:'xxx'....} B 接口 {BB_name:'xxx',BB_code:''}

    如果现在想声明一个类来同时充当这 2 个接口的请求和响应,怎么在拿到 A 的结果直接把 bean 给 B,B 通过方法上的注解或者什么其他手段在发送 B 接口的时候,将 requestBody 的 json field 自动拼上 BB_前缀

    • 用 map 梭哈的话 replace 一下 key 名就好,但是后续应该还会有类似的接口,就想能不能写点什么工具

    • @JsonSerialize 好像会改变整个类的,在方法参数上用好像不生效

    • 现在是写了注解在方法参数里,定义了前缀和后缀 . methodB(@Anno(prefix="BB_")@RequestBody Obj obj)

      • 但是后续不太会操作了.先是写了个自定义的 RequestBodyAdvice,在 afterBodyRead()里面直接改 body 的值,然后 return 后报错了. 现在在看 HandlerMethodArgumentResolver,在想 resolveArgument()里面应该怎么改.

    菜鸡一个,也不知道思路对不对,请大佬们指点一下.

    8 条回复    2023-03-03 12:05:52 +08:00
    wleexi
        1
    wleexi  
       2023-03-02 23:06:37 +08:00
    org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor

    看下这个
    brust
        2
    brust  
       2023-03-02 23:11:45 +08:00
    自定义两个 bean 感觉好点,然后 mapstruct 转一下
    Amber2011
        3
    Amber2011  
    OP
       2023-03-02 23:20:50 +08:00
    @wleexi
    已经在看这个类的接口 HandlerMethodReturnValueHandler 了,还没弄太明白,等明天再研究研究.方向对了就好

    @brust
    现在正在跑的版本是这样的,定义了 2 个 bean,然后互转. 就只是担心后续同类接口都要写 2 个 bean 就折磨了.自己想实现的这个方式写一半能力不足卡住了😂,不太想废掉这中方式,想再研究一下
    litchinn
        4
    litchinn  
       2023-03-03 09:39:16 +08:00
    RequestBodyAdvice, ResponseBodyAdvice 应该可以处理吧,
    以下纯属个人吐槽
    @Anno(prefix="BB_")这种方式感觉不灵活,应该在类上加上两个不同的注解 @ReqSerial @ResSerial 来指定怎么序列化
    然后你会发现真要这么写了,工作量并没有比 2 楼说的方式来的小
    所以个人感觉最好的方式就是用代码生成器定义模板,根据需求直接生成这两个类和相关 mapstruct 的代码,这样效率且代码易读、易维护
    bk201
        5
    bk201  
       2023-03-03 10:23:56 +08:00
    这个不就是 json 序列化改造一下就行了吗? jsonalias 之类的
    wleexi
        6
    wleexi  
       2023-03-03 10:32:38 +08:00
    对, 实现这个接口就可以了。
    wleexi
        7
    wleexi  
       2023-03-03 10:32:55 +08:00
    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
    NativeWebRequest webRequest) throws Exception {
    // TODO 可通过客户端的传递的请求头来切换不同的响应体的内容
    mavContainer.setRequestHandled(true);
    // returnValue = POJO
    ApiResponse apiResponse = ApiResponse.ok(returnValue);
    HttpServletResponse response = (HttpServletResponse) webRequest.getNativeResponse();
    response.addHeader("v", "3");
    ServletServerHttpResponse httpOutMessage = createOutputMessage(webRequest);
    converter.write(apiResponse, MediaType.APPLICATION_JSON, httpOutMessage);
    }
    Aresxue
        8
    Aresxue  
       2023-03-03 12:05:52 +08:00
    写一个 XxxBeanSerializerModifier 继承 com.fasterxml.jackson.databind.ser.BeanSerializerModifier 获取注解做修改

    修改 spring mvc 序列化的 objectMapper 对象,objectMapper.setSerializerFactory(objectMapper.getSerializerFactory()
    .withSerializerModifier(new XxxBeanSerializerModifier()));
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1865 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 00:01 · PVG 08:01 · LAX 16:01 · JFK 19:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.