簡體   English   中英

JAXB空元素解組

[英]JAXB empty element unmarshalling

問題在於:

我在內部使用空元素獲取soap響應(例如... <someDate /> ... ),因此當JAXB想要解析此元素而不是使用null值設置適當的字段時,會null異常。

如何配置JAXB將空元素視為null? 我們能否僅使用JAXB執行此操作(不使用某些第三方解決方法)

基本問題

String不是xsd:date類型的有效值。 要對XML模式有效,可選元素應表示為缺少節點。


為什么基礎問題會影響你

所有JAXB實現都會識別出空String不是xsd:date的有效值。 他們通過將其報告給ValidationEventHandler的實例來完成此操作。 您可以通過執行以下操作自己查看:

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    unmarshaller.setEventHandler(new ValidationEventHandler() {

        @Override
        public boolean handleEvent(ValidationEvent event) {
            System.out.println(event);
            return true;
        }
    });

您正在使用的JAX-WS的實現利用EclipseLink MOXy作為JAXB提供程序。 在您使用的版本中,默認情況下,當遇到嚴重性為ERRORValidationEvent而不是像參考實現那樣的FATAL_ERROR時,MOXy將拋出異常。 從那以后修復了以下錯誤:


解決

如果直接使用JAXB API,則可以簡單地覆蓋默認的ValidationEventHandler 在JAX-WS環境中, XmlAdapter可用於提供自定義轉換邏輯。 我們將利用XmlAdapter來覆蓋處理/從Date轉換的方式。

XmlAdapter(DateAdapter)

import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class DateAdapter extends XmlAdapter<String, Date>{

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

    @Override
    public Date unmarshal(String v) throws Exception {
        if(v.length() == 0) {
            return null;
        }
        return dateFormat.parse(v);
    }

    @Override
    public String marshal(Date v) throws Exception {
        if(null == v) {
            return null;
        }
        return dateFormat.format(v);
    }

}

Java模型(根)

XmlAdapter使用引用@XmlJavaTypeAdapter注解。 如果您希望此XmlAdapter應用於Date所有實例,您可以在包級別注冊它(請參閱: http//blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html )。

import java.util.Date;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlSchemaType(name = "date")
    @XmlJavaTypeAdapter(value=DateAdapter.class, type=Date.class)
    private Date abc;

    @XmlSchemaType(name="date")
    @XmlJavaTypeAdapter(value=DateAdapter.class, type=Date.class)
    private Date qwe;

}

演示代碼

下面是一個獨立的示例,您可以運行以查看一切正常。

jaxb.properties

在使用MOXy作為JAXB提供程序的獨立示例中,您需要在與域模型相同的程序包中包含名為jaxb.propeties的文件,並帶有以下條目(請參閱: http//blog.bdoughan.com/2011/05/指定-eclipselink-moxy-as-your.html )。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

input.xml中

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <abc></abc>
    <qwe>2013-09-05</qwe>
</root>

演示

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum18617998/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

產量

請注意,在編組的XML中,null的Date字段被編組為缺少元素(請參閱: http//blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html )。

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <qwe>2013-09-05</qwe>
</root>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM