JAXB空元素解组 [英] JAXB empty element unmarshalling

查看:92
本文介绍了JAXB空元素解组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题在于:

我得到了内部为空元素的soap响应(例如 ...< someDate /> ; ...
因此当JAXB想要解析这个元素
而不是用 null <设置相应的字段时抛出异常/ code> value。

I get the soap response with empty element inside (e.g. ... <someDate /> ... ) and as a result exception is being throwed when JAXB wants to parse this element instead to set the appropriate field with null value.

如何配置JAXB将空元素视为null?
我们可以只使用JAXB(不使用某些第三方解决方法)

How to configure JAXB to treat empty elements as null ? Can we do this with JAXB only (not using some third-party workarounds)

推荐答案

基本问题



字符串不是 xsd:date 的有效值类型。为了对XML模式有效,可选元素应表示为缺席节点。

Base Problem

Empty String is not a valid value for the xsd:date type. To be valid with the XML schema an optional element should be represented as an absent node.,

所有JAXB实现都会认识到空字符串不是的有效值XSD:日期。他们通过将其报告给 ValidationEventHandler 的实例来完成此操作。您可以通过执行以下操作自行查看:

All JAXB implementations will recognize that empty String is not a valid value for xsd:date. They do this by reporting it to an instance of ValidationEventHandler. You can see this yourself by doing the following:

    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提供者。在您使用的版本中,当遇到严重性 ERROR ValidationEvent 时,MOXy将默认抛出异常而不是 FATAL_ERROR 就像参考实现一样。此后已在以下错误中修复:

The implementation of JAX-WS you are using, leverages EclipseLink MOXy as the JAXB provider. And in the version you are using MOXy will by default throw an exception when a ValidationEvent of severity ERROR is encountered instead of FATAL_ERROR like the reference implementation. This has since been fixed in the following bug:

  • http://bugs.eclipse.org/369994

如果直接使用JAXB API,则可以简单地覆盖默认的 ValidationEventHandler 。在JAX-WS环境中, XmlAdapter 可用于提供自定义转换逻辑。我们将利用 XmlAdapter 来覆盖如何处理转换为 Date 的转换。

If you are using the JAXB APIs directly you could simply override the default ValidationEventHandler. In a JAX-WS environment a XmlAdapter can be used to provide custom conversion logic. We will leverage an XmlAdapter to override how the conversion to/from Date is handled.

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模型(Root) )

使用 @XmlJavaTypeAdapter XmlAdapter c $ c>注释。如果您希望此 XmlAdapter 应用于 Date 的所有实例,您可以在包级别注册它(请参阅:< a href =http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html =noreferrer> http://blog.bdoughan.com/2012/02/ jaxb-and-package-level-xmladapters.html )。

The XmlAdapter is referenced using the @XmlJavaTypeAdapter annotation. If you wish this XmlAdapter to apply to all instances of Date you can register it at the package level (see: 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;

}






演示代码



下面是一个独立的示例,您可以运行以查看一切正常。


Demo Code

Below is a standalone example you can run to see that everything works.

jaxb。属性

在使用MOXy作为JAXB提供程序的独立示例中,您需要包含一个名为 jaxb.propeties 与您的域模型在同一个包中,并带有以下条目(请参阅: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html )。

In a standalone example to use MOXy as your JAXB provider you need to include a file called jaxb.propeties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-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 )。

Note that in the marshalled XML the Date field that was null was marshalled as an absent element (see: 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>

这篇关于JAXB空元素解组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆