jaxb2-maven-plugin生成类缺失@XmlRootElement注解报错问题
问题原因
xjc工具基于WSDL生成Java类时,仅会为WSDL中定义的全局顶级元素对应的类自动添加@XmlRootElement注解。你遇到的autorizacion.ConfirmPayer10属于嵌套引用类型或匿名定义类型,生成时默认不会添加该注解,直接将该类的实例作为根元素做JAXB编组时就会抛出题目中的错误。
解决方案
方案1:使用生成的ObjectFactory包装对象(最推荐,零额外配置)
xjc生成类时会在同包路径下自动生成ObjectFactory类,其中为所有没有@XmlRootElement注解的类型提供了带@XmlElementDecl注解的工厂方法,返回包装后的JAXBElement对象,直接使用该对象做序列化或接口调用即可,示例代码:
// 构造业务对象并填充字段 ConfirmPayer10 request = new ConfirmPayer10(); request.setXxx(xxx); // 用自动生成的工厂类包装对象 ObjectFactory factory = new ObjectFactory(); JAXBElement<ConfirmPayer10> requestElement = factory.createConfirmPayer10(request); // 后续操作传入requestElement即可,不要直接传入ConfirmPayer10的实例
方案2:配置插件自动为生成类添加@XmlRootElement注解
如果不想每次编码都做包装操作,可以修改jaxb2-maven-plugin配置,开启扩展能力让插件生成类时自动补全注解,配置示例如下:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <execution> <id>generate-sri-autorizacion-comprobantes</id> <phase>generate-sources</phase> <goals> <goal>xjc</goal> </goals> <configuration> <outputDirectory>${project.basedir}/target/generated-sources/wsdl</outputDirectory> <packageName>autorizacion</packageName> <sourceType>wsdl</sourceType> <clearOutputDir>false</clearOutputDir> <!-- 开启JAXB扩展支持 --> <extension>true</extension> <sources> <source>${project.basedir}/src/main/resources/PayerWebService.wsdl</source> </sources> <!-- 配置生成参数,自动补全根元素注解 --> <arguments> <argument>-Xsimple</argument> </arguments> </configuration> </execution> </executions> <!-- 引入扩展依赖 --> <dependencies> <dependency> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>0.12.0</version> </dependency> </dependencies> </plugin>
配置完成后重新执行mvn clean generate-sources,生成的ConfirmPayer10类就会自动带上@XmlRootElement注解,可以直接序列化使用。
方案3:手动构造JAXBElement包装对象(临时场景适用)
如果是临时调试或者不方便修改插件配置的场景,可以在序列化前手动构造JAXBElement包装实例,需要自行匹配WSDL中对应元素的命名空间和标签名,示例:
ConfirmPayer10 request = new ConfirmPayer10(); // 填充字段 request.setXxx(xxx); // 替换为你WSDL中对应元素的实际命名空间和节点名 QName qName = new QName("http://对应服务的命名空间", "ConfirmPayer10"); JAXBElement<ConfirmPayer10> element = new JAXBElement<>(qName, ConfirmPayer10.class, request); // 传入element做编组操作即可
注意事项
不要直接手动修改target/generated-sources目录下自动生成的Java类添加@XmlRootElement注解,每次执行mvn clean后该目录下的文件会被重新生成,手动修改的内容会被直接覆盖,导致构建环境复现问题。
内容的提问来源于stack exchange,提问作者Aymen Kanzari
相关产品推荐
相关产品推荐

