简体   繁体   English

JAXB - 豆到XSD或XSD到豆?

[英]JAXB - Beans to XSD or XSD to beans?

I have an existing data model. 我有一个现有的数据模型。 I would like to express this data model in terms of XML. 我想用XML来表达这个数据模型。

It looks like I have two options if I'm to use JAXB: 如果我要使用JAXB,看起来我有两个选择:

  • Create an XSD that mirrors my data model, and use xjc to create binding objects. 创建一个镜像我的数据模型的XSD,并使用xjc创建绑定对象。 Marshalling and unmarshalling will involve creating a "mapping" class that would take my existing data objects and map them to the objects that xjc created. 编组和解组将涉及创建一个“映射”类,它将获取我现有的数据对象并将它们映射到xjc创建的对象。 For example, in my data model I have a Doc class, and JAXB would create another Doc class with basically the same exact fields, and I would have to map from my Doc class to xjc's Doc class. 例如,在我的数据模型中,我有一个Doc类,而JAXB将创建另一个具有基本相同的确切字段的Doc类,并且我必须从我的Doc类映射到xjc的Doc类。
  • Annotate my existing data model with JAXB annotations, and use schemagen to generate an XSD from my annotated classes. 使用JAXB注释注释我现有的数据模型,并使用schemagen从我的注释类生成XSD。

I can see advantanges and disadvantages of both approaches. 我可以看到两种方法的优点和缺点。 It seems that most people using JAXB start with the XSD file. 似乎大多数使用JAXB的人都是从XSD文件开始的。 It makes sense that the XSD should be the gold standard truth, since it expresses the data model in a truly cross-platform way. 因为它以真正的跨平台方式表达数据模型,所以XSD应该是黄金标准的真理是有道理的。

I'm inclined to start with the XSD first, but it seems icky that I have to write and maintain a separate mapping class that shuttles data in between my world and JAXB world. 我倾向于先从XSD开始,但是我必须编写并维护一个单独的映射类来运行我的世界和JAXB世界之间的数据似乎很蠢。

Any recommendations? 有什么建议?

Having the XSD generated from the existing classes sounds to me like the safest way to go. 从现有类生成的XSD听起来像是最安全的方式。

However methinks that unless you know JAXB well then the approach with annotating your own classes may turn out to be extremely frustrating (in both pain and time :)). 然而,除非你很了解JAXB,否则注意你自己的类的方法可能会变得非常令人沮丧(在痛苦和时间:))。

This has happened to me in a related context when I tried to manually extract superclass from JAXB generated classes and then marshal the instances to XML. 当我尝试从JAXB生成的类中手动提取超类,然后将实例封送到XML时,在相关的上下文中发生了这种情况。 I was getting various (cryptic) JAXB exceptions. 我得到了各种(神秘的)JAXB异常。 True, my JAXB knowledge is not that deep yet. 没错,我的JAXB知识还不够深入。

If you insist on using JAXB then I suggest to consider using the first approach (XSD + XJC) as a way to obtain initial JAXB annotations for your classes. 如果你坚持使用JAXB,那么我建议考虑使用第一种方法(XSD + XJC)作为获取类的初始JAXB注释的方法。

You can use XSD + XJC to get an idea how to annotate your own classes. 您可以使用XSD + XJC来了解如何注释自己的类。 Then you can try and fit the correct annotations onto them. 然后,您可以尝试将正确的注释放在它们上面。 Start with the more complex classes (references, inheritance, list of references, list of references to abstract base class) early on. 早期从更复杂的类(引用,继承,引用列表,对抽象基类的引用列表)开始。

Using another technology to generate XSD from non-annotated classes as a kick start on the XSD may help. 使用另一种技术从非注释类生成XSD作为XSD的启动可能会有所帮助。 Or you may go for an XSD that covers most of what your classes use. 或者您可以选择涵盖课程大部分内容的XSD。

If the intention of this effort is to be also able to marshal the instances into XML, then I suggest to be on watch for JAXBElement. 如果这项工作的目的是也能够将实例编组为XML,那么我建议关注JAXBElement。 In some cases (which I cannot pin point due to lack of knowledge) instances will not marshal unless they are wrapped in a JAXBElement. 在某些情况下(由于缺乏知识,我无法指出)实例不会编组,除非它们被包装在JAXBElement中。

We use HyperJAXB to generate persistence tier based on a set of XSDs. 我们使用HyperJAXB基于一组XSD生成持久层。 The generated classes are also used for marshaling. 生成的类也用于编组。 We have plenty of 'fun' making this to work esp. 我们有足够的“乐趣”使这成为特别工作。 because of IDREFs and JAXBElement. 因为IDREF和JAXBElement。

Reading between the lines, I believe the following is true: 在线之间阅读,我相信以下是真的:

  1. You have your desired object model. 您有所需的对象模型。
  2. You have the desired XML schema, or atleast a pretty good idea of how you want it to look. 您拥有所需的XML架构,或者至少非常了解您希望它的外观。

This scenario is usually referred to as "meet in the middle" mapping. 此场景通常称为“中间相遇”映射。 It is only partially solved by JAXB. 它只是由JAXB部分解决。 Luckily since JAXB is a specification, there are other implementations such as EclipseLink JAXB (MOXy) you can use. 幸运的是,由于JAXB是一个规范,因此您可以使用其他实现,例如EclipseLink JAXB(MOXy)。

MOXy offers an XPath based mapping extension that allows you to map between the Java model you have and the XML schema you want: MOXy提供了一个基于XPath的映射扩展,允许您在您拥有的Java模型和所需的XML模式之间进行映射:

You can use xjc and still have only one class with XML annotations that will server as a data object. 您可以使用xjc,但仍然只有一个带有XML注释的类将服务器作为数据对象。 But that is in case you are not re-generating the classes on each built. 但是,如果你没有在每个构建的类上重新生成类。

And as code-generation is in my opinion as in, to the question of where to start from I'd suggest start from the classes. 正如我所认为的代码生成一样,对于从何处开始的问题,我建议从类开始。 Because if you have your classes as a starting point, you will never need to re-generate these classes. 因为如果您将类作为起点,则永远不需要重新生成这些类。 And with time your classes with start to grow - including @XmlTransient , inheritance, helper methods and other (JPA) annotations. 随着时间的推移,您的类开始增长 - 包括@XmlTransient ,继承,辅助方法和其他(JPA)注释。

You're pretty much at the worst possible starting point for JAXB. 你几乎是JAXB最糟糕的起点。 In your position, I'm thinking JiBX might a better bet, it can generate schema from a non-annotated class model, and then bind XML back on the object model at runtime, without using annotations. 在你的位置,我认为JiBX可能是一个更好的选择,它可以从非注释的类模型生成模式,然后在运行时将XML绑定在对象模型上,而不使用注释。

The solution we have gone with is to have a separate project containing all of the data models defined by xml schemas from which java classes are derived using JAXB. 我们使用的解决方案是拥有一个单独的项目,其中包含由xml架构定义的所有数据模型,使用JAXB从中派生java类。 Other projects that use the data models depend on this schemas package. 使用数据模型的其他项目依赖于此模式包。

In this way, all of the "contracts" between projects are defined in a single place, using the nice portable xsd representation. 通过这种方式,项目之间的所有“契约”都使用友好的可移植xsd表示在一个地方定义。 There is no need for any mapping classes because we just use the JAXB generated ones directly. 不需要任何映射类,因为我们只是直接使用JAXB生成的映射类。

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

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