Apache CXF为未在xsd:choice中选择的选项生成nil元素,然后失败模式验证

时间:2015-12-23 19:01:56

标签: java xml xsd jaxb cxf

使用CXF 3.1.3,我的webservice客户端提交了一个无效的jaxb soap请求。它不应该创建两个零元素。当我手动删除soapui测试套件中的两个nil元素时,请求体正确验证xsd模式。

架构部分......

<xsd:complexType name="RequestContentType">
    <xsd:complexContent>
        <xsd:extension base="structures:ObjectType">
            <xsd:choice>
                <xsd:element ref="ilcs:MessageID" />
                <xsd:element ref="nc:CaseDocketID" />
                <xsd:element ref="nc:DateRange" />
            </xsd:choice>
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>

生成的无效请求部分......

        <ns4:RequestContent>
            <ns4:MessageID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <ns2:CaseDocketID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            <ns2:DateRange>
                <ns2:StartDate>
                    <ns2:Date>2015-11-13-07:00</ns2:Date>
                </ns2:StartDate>
                <ns2:EndDate>
                    <ns2:Date>2015-12-22-07:00</ns2:Date>
                </ns2:EndDate>
            </ns2:DateRange>
        </ns4:RequestContent>

在构建请求对象的java7代码中,日期范围是RequestContentType对象中唯一设置的内容。另外两个选项optionsId和caseDocketId未设置。在运行时,messageId和caseDocketId为null。

    DateRangeType dr = new DateRangeType();
    dr.setStartDate(NiemConverter.toDateType(oldest.getSubmittedToHfs()));
    dr.setEndDate(NiemConverter.toDateType(newest.getSubmittedToHfs()));
    RequestContentType rct = new RequestContentType();
    rct.setDateRange(dr);

    StatusRequestType req = new StatusRequestType();
    req.setFIPSCode(proxy(fipsCode));
    req.setRequestContent(rct);

有人可以建议为什么CXF正在为null java引用构建nil元素吗?或者如何阻止它?

下面的文件是由maven cxf-codegen-plugin在“wsdl2java”执行目标中生成的。

package g.i.h.d.c.extension._1;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import gov.niem.release.niem.niem_core._3.DateRangeType;
import gov.niem.release.niem.proxy.xsd._3.String;
import gov.niem.release.niem.structures._3.ObjectType;


/**
 * <p>Java class for RequestContentType complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="RequestContentType"&gt;
 *   &lt;complexContent&gt;
 *     &lt;extension base="{http://release.niem.gov/niem/structures/3.0/}ObjectType"&gt;
 *       &lt;choice&gt;
 *         &lt;element ref="{http://dcss.hfs.illinois.gov/csidews/extension/1.0}MessageID" minOccurs="0"/&gt;
 *         &lt;element ref="{http://release.niem.gov/niem/niem-core/3.0/}CaseDocketID" minOccurs="0"/&gt;
 *         &lt;element ref="{http://release.niem.gov/niem/niem-core/3.0/}DateRange" minOccurs="0"/&gt;
 *       &lt;/choice&gt;
 *       &lt;anyAttribute processContents='lax' namespace='urn:us:gov:ic:ntk urn:us:gov:ic:ism'/&gt;
 *     &lt;/extension&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "RequestContentType", propOrder = {
    "messageID",
    "caseDocketID",
    "dateRange"
})
public class RequestContentType
    extends ObjectType
    implements Serializable
{

    @XmlElement(name = "MessageID", nillable = true)
    protected String messageID;
    @XmlElement(name = "CaseDocketID", namespace = "http://release.niem.gov/niem/niem-core/3.0/", nillable = true)
    protected String caseDocketID;
    @XmlElement(name = "DateRange", namespace = "http://release.niem.gov/niem/niem-core/3.0/", nillable = true)
    protected DateRangeType dateRange;

    /**
     * Gets the value of the messageID property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getMessageID() {
        return messageID;
    }

    /**
     * Sets the value of the messageID property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setMessageID(String value) {
        this.messageID = value;
    }

    /**
     * Gets the value of the caseDocketID property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getCaseDocketID() {
        return caseDocketID;
    }

    /**
     * Sets the value of the caseDocketID property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setCaseDocketID(String value) {
        this.caseDocketID = value;
    }

    /**
     * Gets the value of the dateRange property.
     * 
     * @return
     *     possible object is
     *     {@link DateRangeType }
     *     
     */
    public DateRangeType getDateRange() {
        return dateRange;
    }

    /**
     * Sets the value of the dateRange property.
     * 
     * @param value
     *     allowed object is
     *     {@link DateRangeType }
     *     
     */
    public void setDateRange(DateRangeType value) {
        this.dateRange = value;
    }

}

2 个答案:

答案 0 :(得分:0)

cxf-codegen-plugin生成的代码有nillable="true",因为元素CaseDocketID的定义是nillable="true",请参阅XSD

<xs:element name="CaseDocketID" type="niem-xs:string" nillable="true">
    <xs:annotation>
        <xs:documentation>An identifier used to reference a case docket.</xs:documentation>
    </xs:annotation>
</xs:element>

无法更改元素参考中的nillable,请参阅W3C XML Schema Definition Language (XSD)

  

2如果项目的父级不是&lt; schema&gt;,则以下所有条件均为真:

     

2.1 refname中的一个存在,但不是两者。

     

2.2如果存在ref,则除minOccursmaxOccursid之外不存在非限定属性,并且Schema名称空间中没有子项({{ 1}})除了&lt; annotation&gt;。

之外

Apache CXF Web服务请求有效。

答案 1 :(得分:0)

一位同事为我解决了这个问题。显然,他早些时候曾遇到过这个问题。他构建了一个删除nil元素的xsl文件。然后我将该文件作为资源bean添加到我的jaxws客户端配置中,作为出站xslt功能。 xsl文件通过剥离nil元素来转换出站xml。 saxon-8-dom.jar是必需的依赖项。现在我的出站请求正确验证并被远程服务接受。