如何让XJC生成的JAXB类保留XSD中simpleType的abc:reference属性
解决XJC生成JAXB类时保留abc:reference属性值的方案
核心思路
通过编写自定义XJC插件,在生成JAXB类时自动识别XSD中abc:reference属性的值,并将其以public static final String字段的形式嵌入到对应的simpleType类中。
步骤1:编写XJC自定义插件
创建一个实现com.sun.tools.xjc.Plugin接口的Java类,用于处理XSD中的自定义属性并生成静态字段:
import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JExpr; import com.sun.codemodel.JFieldVar; import com.sun.codemodel.JMod; import com.sun.tools.xjc.Plugin; import com.sun.tools.xjc.outline.ClassOutline; import com.sun.tools.xjc.outline.Outline; import com.sun.tools.xjc.model.CSimpleType; import com.sun.tools.xjc.model.CTypeInfo; import org.xml.sax.ErrorHandler; import javax.xml.namespace.QName; public class ReferenceUrlPlugin extends Plugin { // 对应XSD中abc命名空间的URI private static final String ABC_NAMESPACE_URI = "http://www.mycompany.no/xsd"; private static final String REFERENCE_ATTR_NAME = "reference"; private static final String STATIC_FIELD_NAME = "REFERENCE_URL"; @Override public String getOptionName() { return "Xreference-url"; } @Override public String getUsage() { return " -Xreference-url : 将XSD中abc:reference属性值生成为JAXB类的静态常量字段"; } @Override public boolean run(Outline outline, Options options, ErrorHandler errorHandler) { // 遍历所有生成的类 for (ClassOutline classOutline : outline.getClasses()) { CTypeInfo typeInfo = classOutline.target.getTypeInfo(); // 仅处理命名的simpleType if (typeInfo instanceof CSimpleType) { CSimpleType simpleType = (CSimpleType) typeInfo; // 获取abc:reference属性的值 String referenceUrl = simpleType.getSchemaComponent() .getAttribute(new QName(ABC_NAMESPACE_URI, REFERENCE_ATTR_NAME)); if (referenceUrl != null && !referenceUrl.isBlank()) { JDefinedClass implClass = classOutline.implClass; // 添加public static final String类型的字段 JFieldVar field = implClass.field( JMod.PUBLIC | JMod.STATIC | JMod.FINAL, String.class, STATIC_FIELD_NAME ); // 初始化字段值为referenceUrl field.init(JExpr.lit(referenceUrl)); // 添加字段注释 field.javadoc().add("该类型对应的有效值参考URL"); } } } return true; } }
步骤2:打包插件为Jar文件
- 配置Maven依赖(仅编译时需要):
<dependencies> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-xjc</artifactId> <version>2.3.8</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency> </dependencies>
- 执行
mvn clean package生成插件Jar(如reference-xjc-plugin-1.0.0.jar)。
步骤3:配置XJC使用插件
方式1:Maven jaxb2-maven-plugin配置
在项目的pom.xml中添加插件配置,引入自定义XJC插件:
<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <execution> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <schemaDirectory>${project.basedir}/src/main/resources/xsd</schemaDirectory> <!-- 引入自定义插件 --> <plugins> <plugin> <groupId>your.group.id</groupId> <artifactId>reference-xjc-plugin</artifactId> <version>1.0.0</version> </plugin> </plugins> <!-- 启用自定义插件的参数 --> <arguments> <argument>-Xreference-url</argument> </arguments> </configuration> </plugin> </plugins> </build>
方式2:xjc.sh命令行使用
直接通过命令行指定插件Jar和参数:
xjc.sh -cp ./reference-xjc-plugin-1.0.0.jar -Xreference-url your_schema.xsd
生成效果
执行XJC生成后,MyType类会自动添加静态常量字段:
public class MyType { public static final String REFERENCE_URL = "https://example.com/valid_values.xml"; protected String value; // 自动生成的getter、setter等方法 public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
这样你就可以通过MyType.REFERENCE_URL直接获取该类型对应的有效值URL,满足测试数据生成等场景的需求。
内容的提问来源于stack exchange,提问作者Gogi
相关产品推荐
相关产品推荐

