JAXB空元素解组 [英] JAXB empty element unmarshalling
问题描述
问题在于:
我得到了内部为空元素的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 $的文件c $ c>与您的域模型在同一个包中,并带有以下条目(请参阅: 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屋!