JAX-WS(JAXB):如何将java.util.Date编组为xs:anyType作为xs:date而不是xs:dateTime?

时间:2017-01-18 07:49:09

标签: java web-services date xsd jaxb

我必须与Web Service进行通信,WSDL包含以下complexType:

    <complexType name="KlarigoField">
        <complexContent>
          <sequence>
             <element name="Value" type="{http://www.w3.org/2001/XMLSchema}anyType" minOccurs="0"/>
             <element name="Metadata" type="{http://klarigo.ru/main}KlarigoFieldMetadata" minOccurs="0"/>
           </sequence>
        </complexContent>
   </complexType>

根据这部分,JAXB生成以下类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "KlarigoField", propOrder = {
    "value",
    "metadata"
})
public class KlarigoField {

    @XmlElement(name = "Value", nillable = true)
    protected Object value;
    @XmlElement(name = "Metadata", nillable = true)
    protected KlarigoFieldMetadata metadata;

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public KlarigoFieldMetadata getMetadata() {
        return metadata;
    }

    public void setMetadata(KlarigoFieldMetadata value) {
        this.metadata = value;
    }

}

在一次操作中,我必须将java.util.Date值分配给&#34; Value&#34;我得到以下输出的元素:

<Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:dateTime">
2017-01-25T00:00:00+03:00
</Value>

但我需要获得类型&#34; xs:date&#34;的值,类似的东西:

<Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:date">
2017-01-25
</Value>

默认情况下,JAXB将java.util.Date编组到xs:dateTime。我已经读过,我们可以创建一个自定义适配器,将java.util.Date编组为xs:date,就像回答here一样。问题是我们只能将此适配器应用于java.util.Date字段,而不是java.lang.Objectxs:anyType),而且此字段应该是不同类型值的容器。我该怎么做才能解决我的问题?

更新 我通过创建自定义&#34; date&#34;设法获得了所需的结果。包裹java.util.Date的类型:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "date", namespace = "http://www.w3.org/2001/XMLSchema", propOrder = {
        "value"
    })
    public class Date {

        @XmlValue
        @XmlJavaTypeAdapter(DateAdapter.class)
        @XmlSchemaType(name = "date")
        protected java.util.Date value;

        public java.util.Date getValue() {
            return value;
        }

        public void setValue(java.util.Date value) {
            this.value = value;
        }

    }

日期适配器:

public class DateAdapter extends XmlAdapter<String, Date> {

        private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        @Override
        public Date unmarshal(String stringDate) throws Exception {
            return DatatypeConverter.parseDate(stringDate).getTime();
        }

        @Override
        public String marshal(Date date) throws Exception {
            synchronized (dateFormat) {
                return dateFormat.format(date);
            }
        }
    }

我创建了自定义类型的对象,在那里设置了一个真正的java.util.Date对象,最后将其设置为&#34;对象值&#34;字段:

my.custom.Date customDate = new my.custom.Date();
customDate.setValue(new java.util.Date(....));
klarigoField.setValue(customDate);

最后,我将自定义日期类型添加到WSDL以进行自动生成:

<schema targetNamespace="http://www.w3.org/2001/XMLSchema">
    <complexType name="date">
        <simpleContent>
             <extension base="xs:date"/>
        <simpleContent>
    <complexType>
<schema>

1 个答案:

答案 0 :(得分:1)

是的,你得到了正确的方向,你需要一个XmlAdapter

class DateAdapter extends XmlAdapter<String, Object> {

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public String marshal(Object v) throws Exception {
        if (v.getClass() == Date.class) {
            synchronized (dateFormat) {
                return dateFormat.format(v);
            }
        }
        return v.toString();
    }
    // ...    
}

只要所有不同的类型都正确覆盖toString,您就可以轻松编组。

更多: