请教大家 Jackson 泛型反序列化问题 - V2EX
sdbybyd
V2EX    Java

请教大家 Jackson 泛型反序列化问题

  •  
  •   sdbybyd Oct 13, 2020 4513 views
    This topic created in 2037 days ago, the information mentioned may be changed or developed.
     class R<T> { private T data; } class Item { private R<List<String>> message; } class Channel<T> { private T data; } 
     Channel<Item> i ??? 

    请教下最后一个 Channel<Item> 要怎么反序列化呢?

     JavaType type = mapper.getTypeFactory() .constructParametricType( Channel.class, Item.class); Channel<Item> body = mapper.readValue(str, type); 

    这样做的话报错,R 类型识别不出来

    17 replies    2020-10-13 11:56:22 +08:00
    Cbdy
        1
    Cbdy  
       Oct 13, 2020 via Android
    xuanbg
        2
    xuanbg  
       Oct 13, 2020
    把 List<String>封装成一个对象
    xuanbg
        3
    xuanbg  
       Oct 13, 2020
    @xuanbg 看错题目了,你这个泛型嵌套,获取 type 也要嵌套啊,哪能一下子就得到完整的类型呢。试试看下面的代码
    JavaType r = mapper.getTypeFactory().constructParametricType(R.class, String.class);
    JavaType i = mapper.getTypeFactory().constructParametricType(Item.class, r);
    JavaType c = mapper.getTypeFactory().constructParametricType(Channel.class, i);

    Channel<Item> body = mapper.readValue(str, c);
    xuanbg
        4
    xuanbg  
       Oct 13, 2020
    还是写错了……

    @xuanbg 看错题目了,你这个泛型嵌套,获取 type 也要嵌套啊,哪能一下子就得到完整的类型呢。试试看下面的代码
    JavaType r = mapper.getTypeFactory().constructParametricType(List.class, String.class);
    JavaType i = mapper.getTypeFactory().constructParametricType(Item.class, r);
    JavaType c = mapper.getTypeFactory().constructParametricType(Channel.class, i);

    Channel<Item> body = mapper.readValue(str, c);
    xuanbg
        5
    xuanbg  
       Oct 13, 2020
    好吧……

    JavaType list = mapper.getTypeFactory().constructParametricType(List.class, String.class);
    JavaType r = mapper.getTypeFactory().constructParametricType(R.class, list);
    JavaType item = mapper.getTypeFactory().constructParametricType(Item.class, r);
    JavaType channel = mapper.getTypeFactory().constructParametricType(Channel.class, i);
    qwerthhusn
        6
    qwerthhusn  
       Oct 13, 2020
    mapper.readValue(str, new TypeReference<Channel<Item>>() {});
    就行了

    Item 里面的泛型 Jackson 能取到的,你不用关心
    passerbytiny
        7
    passerbytiny  
       Oct 13, 2020 via Android
    Class 类型的方法参数,实参只接受真实类型,不接受泛型。
    BrbiwsFtd9zDGZqB
        8
    BrbiwsFtd9zDGZqB  
       Oct 13, 2020
    new TypeReference<Channel<Item>>() {}
    qinxi
        9
    qinxi  
       Oct 13, 2020
    0x666666
        10
    0x666666  
       Oct 13, 2020
    楼上说的对,遇到泛型统一 TypeReference 解决就完事了
    GM
        11
    GM  
       Oct 13, 2020
    两个方法:
    一个是楼上说的 new TypeReference<Channel<Item>>() {}
    第二个,简单粗暴,直接定义一个类:
    public static class ChannelItem extends Channel<Item> {}

    后续所有序列化、反序列化都用这个 ChannelItem
    sdbybyd
        12
    sdbybyd  
    OP
       Oct 13, 2020
    @Cbdy @90d0n @GM TypeReference 只能推断顶层类型,会报错,数据成员泛型怎么推断呢?
    sdbybyd
        13
    sdbybyd  
    OP
       Oct 13, 2020
    @xuanbg 你这个是嵌套泛型的做法,但是仔细看下数据成员是泛型怎么搞呢?
    Elroooo0Y
        14
    Elroooo0Y  
       Oct 13, 2020
    item 上面不加泛型
    自己的都不知道 R 的具体类型是什么
    jackson 怎么会知道呢 .

    如果 R 不能表示出来的话 可以在 json 字符里面试试 "class"关键字表示一下具体的泛型类型
    sdbybyd
        15
    sdbybyd  
    OP
       Oct 13, 2020
    @qinxi 你这个是多态时的做法,不能用于复杂泛型吧
    Elroooo0Y
        16
    Elroooo0Y  
       Oct 13, 2020
    @Elroooo0Y

    这么写
    {
    "condition": {
    "class": "com.github.Test",
    "id": {
    "uid": 1000
    },
    "source": 1
    }
    }
    sdbybyd
        17
    sdbybyd  
    OP
       Oct 13, 2020
    统一回复,使用 JsonNode 临时解决了,不能推断的泛型字段单独读取 string 出来后再重新反序列化(这时 JavaType 或 TypeReference 都可以)
    About     Help     Advertise     Blog     API     FAQ     Solana     1012 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 48ms UTC 22:19 PVG 06:19 LAX 15:19 JFK 18:19
    Do have faith in what you're doing.
    ubao msn 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