英文:
Jaxb2Marshaller subclasses scanning
问题
我正在使用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 {
// 生成的代码
}
然后我将其扩展并放在不同的包中:
package com.myapp.extended.someRequest;
class SomeRequestExtended extends com.myapp.generated.SomeRequest {
// 额外的代码
}
然后使用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; 以及其任何父类都不为此上下文所知。
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:567) ~[na:1.8.0_201]
...
有人知道原因是什么,以及如何使其扫描指定的包以找到SomeRequestExtended
类吗?
英文:
I'm using maven-jaxb2-plugin
to generate Java classes according to a WSDL.
Generated Java classes are under package com.myapp.generated
and for example, there is Jaxb2 generated class com.myapp.generated.SomeRequest
:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"someRequestType"
})
@XmlRootElement(name = "someRequest")
public class SomeRequest
{
// generated code
}
which I'm extending then I have it in a different package:
package com.myapp.extended.someRequest;
class SomeRequestExtended extends com.myapp.generated.SomeRequest {
// additional code
}
Then using Spring Boot (v2.2.9) / spring-oxm (v5.2.8) I specify Bean for Jaxb2Marshaller to scan that package:
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.myapp.extended.*");
return marshaller;
}
During runtime, unfortunately, there is a problem it doesn't find it:
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]
...
Does anyone know what is the reason, and how to make it scan specified packages to find the SomeRequestExtended class?
答案1
得分: 0
由于 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
在子类中仍然有效 - 在我的示例中,字段应可见,或者您可以使用 XmlAccessType.PUBLIC_MEMBER
将定义更改为 getter 方法。
提示: 此外,如果存在(通常会有)由 JAXB 生成的 package-info.java
文件,则也应将其复制到一个新的包中,就像在我的示例中一样:package com.myapp.extended.someRequest;
如果没有,解析 marshaller 时可能会出现问题!
英文:
The reason is that the required XmlRootElement on JAXB classes is not inherited in subclasses because interface XmlRootElement doesn't have @Inherited annotation:
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";
}
To solve the issue, you can manually add/copy it from parent class to subclass:
package com.myapp.extended.someRequest;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"someRequestType"
})
@XmlRootElement(name = "someRequest")
class SomeRequestExtended extends com.myapp.generated.SomeRequest {
// additional code
}
Also make sure, that the @XmlAccessorType(XmlAccessType.FIELD)
and @XmlType
are still valid in subclass - in my example, the field should be visible, or you can change the definition to getter method using XmlAccessType.PUBLIC_MEMBER
HINT: Additionally, if there is, and usually is, a file package-info.java
generated by JAXB, then it should also be copied to a new package, like in my example to: package com.myapp.extended.someRequest;
If not there might be problems when resolving classes by marshaller!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论