Jaxb2Marshaller的子类扫描

huangapple go评论82阅读模式
英文:

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!

huangapple
  • 本文由 发表于 2020年9月1日 18:55:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63686278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定