JAXB 怎么实现带泛型 XML 转 Bean。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
DavidDee
V2EX    Java

JAXB 怎么实现带泛型 XML 转 Bean。

  •  
  •   DavidDee 2021 年 8 月 16 日 2130 次点击
    这是一个创建于 1696 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 转换的 xml 格式*(其中 DataTable 节点下 a 、b 字段是 X 类,c 、d 字段是 Y 类的,后续还需要适配更多类)
    <?xml version="1.0" encoding=""?> <DocumentElement> <Result>0</Result> lt;Error></Error> <DataTable> <a>/<a> <b>/<b> </DataTable> <DataTable> <a>/<a> <b>/<b> </DataTable> </DocumentElement> <!--------------------------或者--------------------------> <?xml version="1.0" encoding=""?> <DocumentElement> <Result>0</Result> <Error></Error> <DataTable> <c>/<c> <d>/<d> </DataTable> <DataTable> <c>/<c> <d>/<d> </DataTable> </DocumentElement> 
    • 目的 bean
    @XmlRootElement(name = "DocumentElement") @XmlSeeAlso({X.class, Y.class}) @XmlAccessorType(XmlAccessType.FIELD) public class ResponseEntity <T> { @XmlElement(name = "Result") private String result; @XmlElement(name = "Error") private String error; @XmlAnyElement(lax = true) private List<T> dataTable; public ResponseEntity() { } // getter/setter 省略 } 
    • X 类
    @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class X { private String a; private String b; } 
    • Y 类
    @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Y { private String c; private String d; } 
    • 转换方法
     //获得 JAXBContext 类的新实例。参数为类的地址 JAXBContext cOntext= JAXBContext.newInstance(t.getClass()); //创建一个可以用来将 XML 数据转换为 java 内容树的 Unmarshaller 对象。 Unmarshaller um = context.createUnmarshaller(); //创建一个 StringReader 将 xml 报文转成流 StringReader sr = new StringReader(xml); //调用 unmarshal 进行转换,并把 Object 类型强转为调用者的类型 t = (T) um.unmarshal(sr); //将对象返回给调用者 return t; 

    目前的问题

    • 如果 X 、Y 类 @XmlRootElement 不加 name = "DataTable",转换后的 Bean 的 list 为空
    • 如果 X 、Y 类 @XmlRootElement 其中一个类加 name = "DataTable",转换后的 Bean 的 list 类型内容一直都是那个类
    • 如果 X 、Y 类 @XmlRootElement 都加 name = "DataTable",转换后的 Bean 的 list 类型会不匹配(猜测 java 泛型在编译时类型被擦去, 反射不能确定具体那个类,参考[当 Jaxb 遇到泛型]: https://www.cnblogs.com/mumuxinfei/p/8948299.html)

    不知道各位有没有遇到过或提供一下解决思路。不胜感激

    5 条回复    2021-08-31 15:16:53 +08:00
    DavidDee
        1
    DavidDee  
    OP
       2021 年 8 月 16 日
    算了,都用 DataTable 节点的话不行,我手动这个这点内容吧,然后再使用包装类用不同的 name 解析,不浪费时间了
    cp19890714
        2
    cp19890714  
       2021 年 8 月 16 日   1
    这不是类型擦除导致的, 而是因为你就没有传入具体类型, 程序自然不知道你要反序列化为什么玩意.
    jackson 在反序列化 json 时, 需要传入目标类型的 TypeReference, 其中需要指明泛型的具体类型. 如果没有指定, 同样不能反序列化.
    jaxb 也是一样.

    即使能实现, 那也是通过遍历,或者你指定的一些规则, 去猜测这个泛型可能的具体类型.
    hdfg159
        3
    hdfg159  
       2021 年 8 月 17 日 via Android   1
    用数组
    DavidDee
        4
    DavidDee  
    OP
       2021 年 8 月 17 日
    @cp19890714 感谢回复。其实在之前已经使用过包装类,将具体需要转换的类型放入泛型了,但是还是有问题。
    8bit
        5
    8bit  
       2021 年 8 月 31 日
    用继承的方式解决,DataTable 作为父类,各子类使用自己类名作为 XML 节点名,在转换完之后将该节点名替换为 DataTable,这就解决了泛型未传入类型的问题
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5467 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 05:54 PVG 13:54 LAX 22:54 JFK 01:54
    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