我正在处理的代码是使用jaxb2-maven-plugin
fromorg.codehaus.mojo
从 XSD 模式生成 Java 类。我正在寻找一种自动实现这些类的方法equals()
和hashCode()
方法,但似乎没有办法。我知道还有其他 JAXB2 Maven 插件可以做到这一点(例如 http://confluence.highsource.org/display/J2B/Home),但我想知道你们中是否有人遇到过这个问题,是否有办法修复它。我正在使用xjc
目标生成类。
7 回答
JAXB2 Basics you're mentioning is not a property of maven-jaxb2-plugin
, it is a standalone set of JAXB 2.x plugins you can use with XJC - or jaxb2-maven-plugin
or whatever.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<arguments>
<argument>-Xequals</argument>
<argument>-XhashCode</argument>
</arguments>
</configuration>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.12.0</version>
</dependency>
</dependencies>
</plugin>
What I wanted to ask - why not just use maven-jaxb2-plugin
? It has so much more functionality compared to the Codehaus plugin - including configuration support for JAXB2 plugins.
我强烈反对在您的代码中使用 JAXB 生成的类作为业务对象。JAXB 生成的类是 bean,它们本质上只是将元素信息从 xml 文件移动到 bean 的字段。我个人总是让我的 SOAP 服务将这些生成的 bean 类转换为我的实际业务对象,因为 XML->Java 反之亦然,转换并非一直都是黑白的。请注意,这是我的个人观点,并且希望其他人能够权衡他们在这种情况下所做的事情。
不过,要回答您的问题,请使用不同的插件,或者只使用您的 IDE 来创建一些 equals 和 hashCode 方法。
希望有帮助。
编辑:
我忘了说明我的理由,抱歉。让我们说在您的项目的下一个版本中,您想要为您的 JAXB 生成的类添加更多行为,但还想要对您的模式进行一些更改。现在,您正在重新生成 JAXB 生成的类,将旧的行为放回原处,并使您的应用程序在我看来更容易受到错误的影响。JAXB 生成的类应该反映您的 XML 模式类型(以及您的 SOAP 消息),而不是您的业务逻辑。希望这是有道理的。
这是最简单的方法。请根据您的要求更新版本。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-commons-lang</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>JAXB generate content classes</id>
<phase>generate-sources</phase>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<schemaDirectory>${project.basedir}/src/main/resources/schema</schemaDirectory>
<outputDirectory>${project.build.directory}/generated-sources/jaxb</outputDirectory>
<schemaFiles>**/*.xsd</schemaFiles>
<packageName>com.lexus.web.content.model</packageName>
<arguments>-Xcommons-lang</arguments>
</configuration>
</execution>
</executions>
</plugin>
您可能还需要考虑使用流畅的构建器界面(有助于处理生成的 JAXB 类)和对目录文件的引用,以防您引用 xmldsig-core-schema(加速生成过程,因为没有远程模式来自 W3C 的查询 - 他们的服务器通常会延迟响应)。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>2.0.1</version>
<exclusions>
<exclusion>
<groupId>com.sun.xml</groupId>
<artifactId>jaxb-xjc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.4</version>
<exclusions>
<exclusion>
<groupId>com.sun.xml</groupId>
<artifactId>jaxb-xjc</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>${basedir}/src/main/resources/xsd</schemaDirectory>
<packageName>[your package name goes here]</packageName>
<outputDirectory>${build.directory}/generated/src/main/java</outputDirectory>
<bindingDirectory>${basedir}/src/main/resources/xsd</bindingDirectory>
<extension>true</extension>
<catalog>${basedir}/src/main/resources/xsd-catalog/catalog.cat</catalog>
<extension>true</extension>
<arguments>-Xfluent-api -Xequals -XhashCode -XtoString</arguments>
</configuration>
</plugin>
目录文件如下所示:
--
sample catalog file.
double hyphens are used to begin and end a comment section.
--
SYSTEM "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" "xmldsig-core-schema.xsd"
这是 xmldisg-core-schema.xsd 的链接:http: //www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd
请注意,链接没有断开 - W3C 服务器只是将响应延迟了几秒钟。如果在包括 JAXB 生成的自动化构建过程中发生这种情况,我会很麻烦吗?
我的答案是针对那些无法负担任何第三方对他们生成的代码的依赖的人。
org.jvnet.jaxb2_commons :jaxb2-basics插件在生成的代码中添加了许多org.jvnet
包含,您的项目将依赖于org.jvnet.jaxb2_commons:jaxb2-basics-runtime
.
org.andromda.thirdparty.jaxb2_commons :commons-lang-plugin插件生成的代码依赖于commons-lang:commons-lang
. 根据具体情况,这种依赖性可能更容易承受。
我终于找到了这个源代码,它可能在某个时候包含在com.sun.xml.bind:jaxb-xjc中(版本 2.2.4 ?),但在那之前,除了编写自己的插件之外,我看不到任何其他解决方案.
PS:我无法访问confluence.highsource.org,我得到了 404。我想这可能会有所帮助。
PPS:在我的情况下,我正在构建的应用程序是针对具有非常有限的一组允许的 Java 库(不协调的安全限制)的环境。我有点失望,因为在生成的源代码中jaxb2_commons
包含一堆org.jvnet
依赖项,只是为了添加一个无聊的equals
方法。我能理解jvnet的策略,他们的工具很强大,我可能只是在尝试和使用大锤来破解。尽管如此,我还是很遗憾地注意到,很难找到适合我情况的工具。
还有一个用于 JAXB 的 fluent-builder 插件,它不一定会生成对第三方代码的依赖关系。另外,它是一个真正的“Builder”设计模式,而“fluent-api”插件只是为生成的类添加了类似builder的方法。它是:https ://github.com/mklemm/jaxb2-rich-contract-plugin 它还具有使生成的类不可变的选项,并且可以生成将现有对象的状态复制到新的构建器实例中的方法,还支持“部分”对象副本。
对我来说,最简单的方法是使用maven-jaxb2-plugin
(如接受的答案中所述):
- 在 pom.xml 中添加
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.12.0</version>
</dependency>
- 添加插件
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources</schemaDirectory>
<generateDirectory>target/generated-sources</generateDirectory>
<generatePackage>my.package</generatePackage>
</configuration>
</execution>
</executions>
<configuration>
<extension>true</extension>
<args>
<arg>-XtoString</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.12.0</version>
</plugin>
</plugins>
</configuration>
</plugin>
看
- JAXB2 基础插件maven-jaxb2-plugin 文档/示例
- 在 Java 中生成 JAXB 类时添加 toString、hashCode、equals - 另一个类似的 stackoverflow 线程