【问题标题】:Add toString, hashCode, equals while generating JAXB classes in Java在 Java 中生成 JAXB 类时添加 toString、hashCode、equals
【发布时间】:2020-08-05 04:43:30
【问题描述】:

我正在尝试使用 Java 以编程方式从 XSD 文件生成 JAXB 类。我使用以下代码 sn-p 来实现:

....
import java.io.File;
import java.io.IOException;
import org.xml.sax.InputSource;
import com.sun.codemodel.JCodeModel;
import com.sun.tools.xjc.api.S2JJAXBModel;
import com.sun.tools.xjc.api.SchemaCompiler;
import com.sun.tools.xjc.api.XJC;
....
....
public static void generateJaxb(String schemaPath,
                                    String outputDirectory,
                                        String packageName) throws DataLoadingException
{
    try {
        // Setup schema compiler
        SchemaCompiler sc = XJC.createSchemaCompiler();
        sc.forcePackageName(packageName);

        // Setup SAX InputSource
        File schemaFile = new File(schemaPath);
        InputSource is = new InputSource(schemaFile.toURI().toString());

        // Parse & build
        sc.parseSchema(is);
        S2JJAXBModel model = sc.bind();

        JCodeModel jCodeModel = model.generateCode(null, null);
        jCodeModel.build(new File(outputDirectory));
    } catch (IOException exec) {
        LOGGER.error("Error while generating JAXB classes: " + exec);
    }
}

生成的类仅包含字段的getter 方法。但是,我也想包含hashCodeequalssetter 方法。生成代码时如何做到这一点?

【问题讨论】:

    标签: java jaxb xjc jaxb2-basics


    【解决方案1】:

    在 GitHub 网站上,您会找到 JAXB2 Basics project,它提供了一组通用的 JAXB 实用插件,其中包括 4 个应该解决您想要实现的目标:

    1. Equals Plugin
    2. HashCode Plugin
    3. Setters Plugin
    4. ToString Plugin

    还有其他可用的插件涵盖Java 域对象的类似常见方面。

    配置

    XML Schema 配置的角度来看,您将添加如下所示的引用:

    <?xml version="1.0"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:basic="http://jaxb2-commons.dev.java.net/basic"
        xmlns:equals="http://jaxb2-commons.dev.java.net/basic/equals"
        xmlns:hashCode="http://jaxb2-commons.dev.java.net/basic/hashCode"
        xmlns:toString="http://jaxb2-commons.dev.java.net/basic/toString"
        jaxb:extensionBindingPrefixes="basic equals hashCode toString">
        <!-- ... -->
    </xs:schema>
    

    还有其他可用选项,例如定义在生成equals( that ) 实现、toString() 实现等时应忽略的对象属性。

    Java 代码生成

    Java 的角度来看,插件通常让生成的类实现interface;例如,包含equals( that ) 实现的生成类将实现 [Equals][6] 接口。

    插件使用的设计方法通常会产生两种实现方式:

    1. 简单/标准实现,例如equals( that ) 方法(使用Equals Plugin 时)。
    2. 一个更复杂的实现,包括locatorstrategy 参数,它允许您实现自定义处理(如果您愿意)。对于这些,您将看到一个方法签名,例如:equals( thisLocator, thatLocator, that, strategy)

    构建/运行时

    从运行时的角度来看,您必须包含 JAXB2 Basics Runtime jar 并提供选项参数,例如:-Xequals-XhashCode-XtoStringAntMaven 提供了使用 JAXB2 基础知识的示例,如果您使用其中任何一个来执行构建,JAXB2 Basics User Guide 中提供了更多与构建相关的详细信息。

    【讨论】:

    • 哇,好答案。小补充:我已将代码移至 GitHub:github.com/highsource/jaxb2-basics
    • 感谢@Sean。我知道 JAXB2 Basics Runtime jar 中存在的插件,但找不到将它们包含到我的代码中的方法,因为它们不是 com.sun.tools.xjc.Plugin 类的子级。
    • @ArkaGhosh 它们Plugin的子类。
    • @lexicore 我不认为有一个 SimpleToString 插件在工作?
    • @OrangeDog 不,没有SimpleToString 插件。
    【解决方案2】:

    更新 下面的答案不正确。我被界面误导了,generateCode 目前真的没有对插件做任何事情。正如@Sidola 指出的那样,您应该改用SchemaCompiler

    除了@SeanMickey 的回答,我将讨论代码生成。

    • 将 JAXB2-Basics JAR 添加到您的类路径中。
    • 实例化
      • org.jvnet.jaxb2_commons.plugin.tostring.ToStringPlugin
      • org.jvnet.jaxb2_commons.plugin.equals.EqualsPlugin
      • org.jvnet.jaxb2_commons.plugin.hashcode.HashCodePlugin
      • org.jvnet.jaxb2_commons.plugin.setters.SettersPlugin
    • ...或任何您需要的。
    • 将插件作为第一个参数传递给model.generateCode(plugins errorListener)

    对了,为什么要以编程方式生成代码?

    【讨论】:

    • 非常感谢@lexicore。这正是我所需要的(com.sun.tools.xjc.Plugin 班级的孩子)。
    • 回答您的问题 - 我正在尝试构建一个框架,该框架将 XSD 作为输入并生成所需的 Entity 类和列族定义以与 Datastax Cassandra 交互。在其中一个步骤中,需要生成 JAXB 类。
    • @ArkaGhosh 我问的原因是您将生成必须首先编译的 Java 代码。这通常是在构建中发生的情况,因此通常只有在您开发构建工具时才有意义。
    • @lexicore 将插件传递给generateCode 方法实际上有什么作用吗?我今天遇到了这个问题,并注意到在 2.2.11 中找到的 JAXBModelImpl 没有对该方法中的插件做任何事情,如 here 所示。我不得不将它们作为选项添加到 SchemaCompiler。
    • @Sidola 嗯,你是对的。我被界面误导了。 generateCode 真的对插件没有任何作用。
    【解决方案3】:

    对我来说,最简单的方法是使用JAXB2 Basics Plugins

    1. 在pom.xml中添加&lt;dependencies&gt;
    <dependency> 
        <groupId>org.jvnet.jaxb2_commons</groupId>
        <artifactId>jaxb2-basics</artifactId>
        <version>0.11.1</version>
    </dependency>
    
    1. 添加插件
    <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.11.1</version>
                </plugin>
            </plugins>
        </configuration>
    </plugin>
    

    mvn clean install 之后生成的类会是这样的:

    package my.package
    public class MyClass implements Equals2, HashCode2, ToString2 {
    
    }
    

    酸:https://github.com/highsource/jaxb2-basics/wiki/Using-JAXB2-Basics-Plugins

    【讨论】:

    • 你能给出完整的使用说明吗?我在 pom 中添加了依赖项和插件,称为 mvn clean install 并且没有任何更改..
    • @NightEagle 您是否完全按照我分享的方式复制了配置?和相同的 jaxb2_commons 版本?如果你还没有解决,请分享 pom 文件。更新了生成的类的样子。
    • 解决了我的问题。应该使用 部分,而不是 。或者在pluginManagement中定义插件描述和配置,也可以添加到plugins section
    • @NightEagle,确实如此。很高兴听到你解决了。如果这对您有所帮助,您可以随时为答案投票;)
    猜你喜欢
    • 2013-09-25
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 2011-06-24
    相关资源
    最近更新 更多