Spring RestTemplate Jackson 网络请求 json 类型匹配错误问题,是否有更优雅的解决方式? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nnegier
V2EX    Java

Spring RestTemplate Jackson 网络请求 json 类型匹配错误问题,是否有更优雅的解决方式?

  •  
  •   nnegier 2023-04-03 21:18:30 +08:00 2133 次点击
    这是一个创建于 925 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以下代码意思:请求一个接口,要求返回 Result<GlobalUser&g;。

    ResponseEntity<Result> respOnse= restTemplate.exchange(url, HttpMethod.PUT, null, Result.class); //① if (response.getStatusCode().is2xxSuccessful()){ Result<GlobalUser> result = response.getBody(); if(result.getCode()==200){ GlobalUser globalUser = result.getData(); //这行代码会出错 } } 

    报错内容:java.util.LinkedHashMap cannot be cast to cn.timetr.server.bean.GlobalUser 也就是说,一个 json 对象给我匹配成键值对 HashMap 了,我估计是上面第一行代码①导致的。

    于是我想写成这样:ResponseEntity<Result<GlobalUser>> respOnse= restTemplate.exchange(url, HttpMethod.PUT, null, Result<GlobalUser>.class); 但这样不行,Result<GlobalUser>.class 报错,不能这样写,但我想按这个思路寻求有何解? 当然不按这个思路,可以将报错代码用 Mapper 转换一下改成这样,GlobalUser globalUser = new ObjectMapper().convertValue(result.getData(), GlobalUser.class);,但这样就导致了每次写相关代码都要手动转换一下并不优雅。

    10 条回复    2023-04-04 12:24:03 +08:00
    Saxton
        1
    Saxton  
       2023-04-03 21:23:51 +08:00
    // 使用 ParameterizedTypeReference 进行包装
    ParameterizedTypeReference<Result<GlobalUser>> reference = new ParameterizedTypeReference<Result<GlobalUser>>() {};
    ResponseEntity<Result<GlobalUser>> respOnse= restTemplate.exchange(url, HttpMethod.PUT, null, reference); //①
    if (response.getStatusCode().is2xxSuccessful()){
    Result<GlobalUser> result = response.getBody();
    if(result.getCode()==200){
    GlobalUser globalUser = result.getData(); //这行代码会出错
    }
    }
    nnegier
        2
    nnegier  
    OP
       2023-04-03 21:32:55 +08:00
    @Saxton 看来 new 是免不了的了,不过这种方式比 Mapper 转换要优雅许多,语义也要更清晰。不过我挺惭愧的,因为我之前在看方法重载时看到了,也去搜了,但还是跑来问了
    Saxton
        3
    Saxton  
       2023-04-03 21:35:19 +08:00
    @nnegier 最优解决方案了,不要去试图避免 new ,如果你使用 mapper 方式只会更麻烦。
    xuanbg
        4
    xuanbg  
       2023-04-03 23:13:06 +08:00
    我在项目里,定义的 Result 对象里面,data 字段的类型用 Object 而不是泛型来规避这种问题。
    xuanbg
        5
    xuanbg  
       2023-04-03 23:17:58 +08:00
    或者,ResponseEntity<Result> respOnse= restTemplate.exchange(url, HttpMethod.PUT, null, Result.class);这行代码我会写成:ResponseEntity< GlobalUser > respOnse= restTemplate.exchange(url, HttpMethod.PUT, null, GlobalUser.class);对的,Result 是个泛型类,那么 exchange 这个方法指定的类型应该是 Result 对象中的 data 字段的类型才对。
    humpy
        6
    humpy  
       2023-04-03 23:24:17 +08:00
    可以试试 feign ,你这个接口定义一个 interface 就实现了

    @FeignClients(url=${xxx.url})
    interface Api {

    @PutMapping("/xxx")
    Result<GlobalUser> xxx();
    }
    Leviathann
        7
    Leviathann  
       2023-04-04 00:20:37 +08:00
    java 半擦除,可以通过继承获取泛型参数
    petercui
        8
    petercui  
       2023-04-04 09:23:14 +08:00
    首先 ObjectMapper 每个工程基本上只需要维护一个实例,并不需要每次都 new 出来。

    其次,OP 有空还得好好看看范型部分。
    nnegier
        9
    nnegier  
    OP
       2023-04-04 12:22:40 +08:00
    @Leviathann 是说有比一楼更优雅的方式吗?
    nnegier
        10
    nnegier  
    OP
       2023-04-04 12:24:03 +08:00
    @petercui 你是指静态吧,我最开始就是这样想的,至于说每次 new 是指的一楼优雅方式需要每次 new ParameterizedTypeReference ,不是说要 new ObjectMapper 。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3152 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 10:55 PVG 18:55 LAX 03:55 JFK 06:55
    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