问题描述
我正在使用maven-jaxb2-plugin
根据WSDL生成java类。
生成的java类在软件包com.myapp.generated
下,例如,Jaxb2生成的类com.myapp.generated.someRequest
:
@XmlAccessorType(XmlAccesstype.FIELD)
@XmlType(name = "",propOrder = {
"someRequestType"
})
@XmlRootElement(name = "someRequest")
public class SomeRequest
{
// generated code
}
package com.myapp.extended.someRequest;
class SomeRequestExtended extends com.myapp.generated.someRequest {
// additional code
}
然后使用Spring Boot(v2.2.9)/ spring-oxm(v5.2.8),我为Jaxb2Marshaller指定Bean来扫描该软件包:
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.myapp.extended.*");
return marshaller;
}
不幸的是,在运行时出现一个找不到的问题:
class package com.myapp.extended.someRequest.someRequestExtended; nor any of its super class is kNown to this context.
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:567) ~[na:1.8.0_201]
...
有人知道原因是什么,如何使它扫描指定的软件包以找到SomeRequestExtended类?
解决方法
原因是JAXB类上必需的XmlRootElement没有在子类中继承,因为接口XmlRootElement没有@Inherited注释:
package javax.xml.bind.annotation;
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
public @interface XmlRootElement {
java.lang.String namespace() default "##default";
java.lang.String name() default "##default";
}
要解决此问题,您可以手动将其从父类添加/复制到子类:
package com.myapp.extended.someRequest;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "",propOrder = {
"someRequestType"
})
@XmlRootElement(name = "someRequest")
class SomeRequestExtended extends com.myapp.generated.SomeRequest {
// additional code
}
还要确保@XmlAccessorType(XmlAccessType.FIELD)
和@XmlType
在子类中仍然有效-在我的示例中,该字段应该可见,或者您可以使用{{1}将定义更改为getter方法}
提示:此外,如果存在(通常是)由JAXB生成的文件XmlAccessType.PUBLIC_MEMBER
,则还应该将其复制到新的程序包中,例如示例为:package-info.java
如果不是通过marshaller解析类时可能会出现问题!