繁体   English   中英

jaxb 按类型解组到对象

[英]jaxb unmarshal to object by type

我想根据xml解析出不同的类型,当header=1然后User,header=2然后Order等,例如:

<entity>
  <header>1</header>
  <body>
    <userId>1</userId>
    <userName>jonh</userName>
    ...
  <body>
</entity>
<entity>
  <header>2</header>
  <body>
    <orderId>1</orderId>
    <orderNo>20200101</orderNo>
    ...
  <body>
</entity>

如何实现这个功能?

Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object object = unmarshaller.unmarshal(xml);

我会试试这个:在解组时提供类型。 所以也许做这样的事情:创建一个瞬态外观对象:

public class XmlEntityFacade {

   private int header;
   private Object body;

   //getters and setters...

}

然后在解组时投射这种类型:

...
XmlEntityFacade facade = (XmlEntityFacade) unmarshaller.unmarshal(xml);

然后,您可以通过调用 .getHeader() 和使用 .getBody()(您提供的 XmlEntityFacade 类的获取器)调用 body 来访问 的值。 然后根据值将所需的类型转换为对象。

public class TwiceUnmarshalTest {

    @Data
    @ToString
    public static abstract class HeaderResponse {
        private String header;
    }

    @XmlRootElement(name = "entity")
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class XmlHeaderResponse extends HeaderResponse {
    }

    private final String xml = "<entity>" +
            "  <header>2</header>" +
            "  <body>" +
            "    <orderId>1</orderId>" +
            "    <orderNo>2020</orderNo>" +
            "  </body>" +
            "</entity>";

    @SuppressWarnings("unchecked")
    public static <T> T unmarshal(Reader reader, Class<T> typeClass) throws Exception {
        JAXBContext jaxbContext = JAXBContext.newInstance(typeClass);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        return (T) unmarshaller.unmarshal(reader);
    }

    @Test
    public void headerResponse() throws Exception {
        HeaderResponse response = unmarshal(new StringReader(xml), XmlHeaderResponse.class);
        System.out.println(response);
    }

    @ToString(callSuper = true)
    public static abstract class Response<T> extends HeaderResponse {
        @XmlAnyElement(lax = true)
        public T body;
    }

    @Data
    @XmlRootElement(name = "body")
    public static class Order {
        private String orderId;
        private String orderNo;

    }

    @XmlRootElement(name = "entity")
    @XmlSeeAlso({Order.class})
    public static class OrderResponse extends Response<Order> {
    }

    @Test
    public void response() throws Exception {
        XmlHeaderResponse response = unmarshal(new StringReader(xml), XmlHeaderResponse.class);
        System.out.println(response);
        //TwiceUnmarshalTest.HeaderResponse(header=2)
        if (response.getHeader().equals("2")) {
            OrderResponse orderResponse = unmarshal(new StringReader(xml), OrderResponse.class);
            System.out.println(orderResponse);
  //TwiceUnmarshalTest.Response(super=TwiceUnmarshalTest.HeaderResponse(header=2), body=TwiceUnmarshalTest.Order(orderId=1, orderNo=2020))
        }
    }
}

解组两次,只需先获取标题,然后获取实体。 不是很好,但可以使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM