Jaxb2Marshaller 子类扫描
Jaxb2Marshaller subclasses scanning
我正在使用 maven-jaxb2-plugin
根据 WSDL 生成 Java classes。
生成的 Java classes 在包 com.myapp.generated
下,例如,有生成的 Jaxb2 class 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 class?
原因是 JAXB classes 上所需的 XmlRootElement 未在子classes 中继承,因为接口 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";
}
要解决此问题,您可以手动 add/copy 从父级 class 到子级 class:
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
在 subclass 中仍然有效 - 在我的示例中,该字段应该是可见的,或者您可以将定义更改为getter 方法使用 XmlAccessType.PUBLIC_MEMBER
HINT:此外,如果存在并且通常存在由 JAXB 生成的文件 package-info.java
,则还应将其复制到一个新包,就像我的示例中的那样: package com.myapp.extended.someRequest;
如果没有,则在通过 marshaller 解析 classes 时可能会出现问题!
我正在使用 maven-jaxb2-plugin
根据 WSDL 生成 Java classes。
生成的 Java classes 在包 com.myapp.generated
下,例如,有生成的 Jaxb2 class 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 class?
原因是 JAXB classes 上所需的 XmlRootElement 未在子classes 中继承,因为接口 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";
}
要解决此问题,您可以手动 add/copy 从父级 class 到子级 class:
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
在 subclass 中仍然有效 - 在我的示例中,该字段应该是可见的,或者您可以将定义更改为getter 方法使用 XmlAccessType.PUBLIC_MEMBER
HINT:此外,如果存在并且通常存在由 JAXB 生成的文件 package-info.java
,则还应将其复制到一个新包,就像我的示例中的那样: package com.myapp.extended.someRequest;
如果没有,则在通过 marshaller 解析 classes 时可能会出现问题!