相关疑难解决方法(0)

JAXB元素既可选又可以为nillable

我重新格式化了这个问题,希望能让我的意图更加清晰.

架构
我正在编写一些Web服务,我将使用JAX-WS自行发布.我们已经使用了一段时间的过程是首先编写一个仅定义请求和响应对象的模式.这将被发送给客户以批准xml消息的结构.我不想自己编写整个wsdl,因为它比基本模式更复杂.

接下来,我使用JAXB命令xjc根据模式中的请求和响应类型生成类.然后,我将此类用作参数,并在JAX-WS带注释的端点类上返回类型.

现在这给了我一个我可以打电话的网络服务.它使我能够更好地控制发送和返回的xml,但也可以自动完成写入完整wsdl所需的重复.

问题
在模式中,我有一个这样的元素:

<xs:element name="myElement" type="xs:string" nillable="true" minOccurs="0" /> 
Run Code Online (Sandbox Code Playgroud)

所以我想区分用户设置null或空白.然后生成的类具有此属性.

@XmlElementRef(name = "myElement", namespace = "/mynamespace", type = JAXBElement.class)
protected JAXBElement<String> myElement;
Run Code Online (Sandbox Code Playgroud)

这样做的结果是元素既不​​是可填充的也不是可选的.JAX-WS作为wsdl的一部分写入的模式已将元素设置为必需而不是nillable,如果我关闭模式验证,我仍然无法将nil传递给我的对象.

事情尝试
如果我将其更改为必需和​​可用,那么我得到这个生成的代码.

@XmlElement(required = true, nillable = true)
protected String myElement;
Run Code Online (Sandbox Code Playgroud)

如果我将其更改为可选而不是nillable,那么我将获得此生成的代码.

protected String myElement
Run Code Online (Sandbox Code Playgroud)

因此,如果您使用JAXB,您可以使用或不是两者.完全令人失望!

我也尝试手动将生成的类更改为这样.

@XmlElementRef(name = "myElement", namespace = "/mynamespace", type = JAXBElement.class, required=false)
protected JAXBElement<String> myElement;
Run Code Online (Sandbox Code Playgroud)

这现在使元素可选,但我仍然无法将其设置为nil.这样做会导致JAXBElement的值为空字符串.只有当你关闭模式验证时才会这样做,因为生成的JAX-WS wsdl/schema没有将元素设置为nillable,因此它不是有效的请求.

总结
我相信这是JAXB的一个错误.@XmlElementRef注释具有将其设置为不需要的属性,但没有将该字段设置为可空的属性.

@XmlElement注释具有必需和可空的属性,但这些只会导致null对象,因此无法区分xml中未包含的元素或包含但为null的元素.这就是您需要将@XmlElementRef与JAXBElement一起使用的原因.

我认为这个bug包含两个问题.首先,xjc命令应生成required = false的元素.其次,@ xmlElementRef应该有一个属性来设置元素是否可以为空,这也应该设置.

有谁知道修复/解决方法?我试过谷歌搜索但只发现人们在没有答案的情况下问同样的问题.这通常意味着它不可能...... TIA.

另外
我使用的是jaxb 2.2.6,而maven插件是jaxb2-maven-plugin 1.5.

java xml jax-ws jaxb

10
推荐指数
2
解决办法
4万
查看次数

在@XmlAttribute中使用Guava的Optional

我想设置一个带JAXB注释的Java类,以下列格式生成一些XML:

<page refId="0001">
    <title>The title of my page</title>
</page>
Run Code Online (Sandbox Code Playgroud)

"refId"字段是可选的,所以我想使用Guava的Optional构造来引用内存中的字符串.我看到使用泛型@XmlJavaTypeAdapter解压缩包装在Guava的Optional中,如果您使用的是元素(即使这不是原始问题),它会提供一个完整的示例,但是您如何设置XML属性的注释?

这是我到目前为止所拥有的:

@XmlRootElement(name="page")
public final class Page {
    @XmlAttribute
    @XmlJavaTypeAdapter(OptionalAdapter.class)
    private Optional<String> refId;

    @XmlElement
    private String title;

    ... getters/setters, default constructor, etc.
}
Run Code Online (Sandbox Code Playgroud)

而OptionalAdapter是一个简单的XmlAdapter:

public class OptionalAdapter<T> extends XmlAdapter<T, Optional<T>> {

    @Override
    public Optional<T> unmarshal(T v) throws Exception {
        return Optional.fromNullable(v);
    }

    @Override
    public T marshal(Optional<T> v) throws Exception {
        if (v == null || !v.isPresent()) {
            return null;
        } else {
            return v.get();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试针对上面的代码加载单元测试时,它在初始化期间立即失败,但是如果我将注释更改为@XmlElement,测试将运行并通过,但显然将refId设置为子元素而不是属性.

提前致谢!

java xml jaxb guava

5
推荐指数
1
解决办法
1161
查看次数

标签 统计

java ×2

jaxb ×2

xml ×2

guava ×1

jax-ws ×1