使用jaxb从一个xml文档生成两个对象

时间:2017-09-05 07:27:20

标签: java xml jaxb

我正在创建一个使用xml文档并从该文档创建两个对象的rest api。然后使用hibernate将对象保存在数据库中。这就是我现在所拥有的:

@PUT
@Path("saveVehicle")
@Consumes("application/xml;charset=utf-8")
@Produces("text/plain")
public String saveVehicleData(String xml) {
    DBClient client = new DBClient();
    Session session = client.getVehicleSession();
    JAXBContext jaxbContext;

    try {
        Reader reader = new StringReader(xml);
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader xmlReader = factory.createXMLStreamReader(reader);

        jaxbContext = JAXBContext.newInstance(VehicleData.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        VehicleData vehicle = (VehicleData) jaxbUnmarshaller.unmarshal(xmlReader);

        session.saveOrUpdate(vehicle);
        session.flush();

        jaxbContext = JAXBContext.newInstance(VehicleOwner.class);
        jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        VehicleOwner owner = (VehicleOwner) jaxbUnmarshaller.unmarshal(xmlReader);

        session.saveOrUpdate(owner);
        session.flush();

        return vehicle.getRegistrationNo() + " " + owner.getName();
    } catch (JAXBException e) {
        e.printStackTrace();
        return "JAXBException " + e.getMessage() + "\nCaused by " + e.getCause();
    } catch (XMLStreamException e) {
        e.printStackTrace();
        return "XMLStreamException " + e.getMessage();
    }
}

如您所见,此方法应该将xml作为字符串。然后它将从该文档生成车辆和车主。该文档包含有关车辆及其所有者的信息,但我希望它们位于不同的数据库表中。 这些类对我想要存储在数据库中的所有字段使用jaxb注释。 但是,当我尝试运行它时,我得到以下stacktrace:

java.lang.ClassCastException: org.package.VehicleOwner cannot be cast to org.package.VehicleData
org.package.rest.LoginController.saveVehicleData(LoginController.java:369)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473)
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

在我为车主添加映射之前,我能够实例化VehicleData并将其存储在数据库中。但现在似乎期望将此xml文档映射到VehicleOwner。我认为可以将文档映射到不同的类。那不是这样吗?如果是的话,我该怎么做?

1 个答案:

答案 0 :(得分:0)

可以将文档映射到不同的类,但显然你不这样做。刚做:

    jaxbContext = JAXBContext.newInstance(VehicleData.class);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    VehicleData vehicle = (VehicleData) jaxbUnmarshaller.unmarshal(xmlReader);

不会将XML结构神奇地映射到VehicleData结构。您必须定义或生成映射,以便相同的XML将映射到不同JAXB上下文中的不同结构(VehicleData / VehicleOwner)。你还必须确保这些上下文不相交(我猜他们会这样做)。