[英]JAXB Bindings File Sets @XmlElement type to String instead of XMLGregorianCalendar
我正在嘗試創建一個XmlAdapter
,它接受XMLGregorianCalendar
並輸出XMLGregorianCalendar
。 目的是簡單地在解組數據時從元素中刪除時區數據。
它看起來像這樣:
public class TimezoneRemoverAdapter extends XmlAdapter<XMLGregorianCalendar, XMLGregorianCalendar> {
public XMLGregorianCalendar unmarshal(XMLGregorianCalendar xgc) {
if(xgc == null) {
return null;
}
xgc.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
return xgc;
}
public XMLGregorianCalendar marshal(XMLGregorianCalendar xgc) {
return xgc;
}
}
這適用於以下代碼:
public class FooElement {
@XmlElement(name="bar-date")
@XmlJavaTypeAdapter(TimezoneRemoverAdapter.class)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar barDate;
}
不幸的是,當我使用jaxb-bindings.xml
文件生成代碼時,上面的代碼如下所示:
public class FooElement {
@XmlElement(name="bar-date", type=java.lang.String.class)
@XmlJavaTypeAdapter(TimezoneRemoverAdapter.class)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar barDate;
}
它將類型設置為String
,因此我的上述方法不起作用。 String
類型設置將覆蓋它應該是的XMLGregorianCalendar
類型。 我可以手動更改它,但我不必記住每次重新生成jaxb文件時都要更新它。 有沒有人知道是否有手動設置@XmlElement
類型或忽略它的選項?
這是jaxb-bindings.xml
文件的相關部分:
<jxb:bindings node=".//xs:element[@name=bar-date]">
<jxb:property>
<jxb:baseType>
<jxb:javaType name="javax.xml.datatype.XMLGregorianCalendar" adapter="foo.bar.TimezoneRemoverAdapter" />
</jxb:baseType>
</jxb:property>
</jxb:bindings>
總結:
yyyy-MM-ddXXX
格式) XXX
部分(日期本身不發送任何時區,日期只是一個數字) 所以這可能是一個示例模式:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<element name="foo">
<complexType>
<sequence>
<element name="bar" type="date" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
</element>
</schema>
這可能是一個示例數據:
<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="foo.xsd">
<bar>2014-01-01+06:00</bar>
</foo>
這是JAXB注釋類
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo implements Serializable
{
private static final long serialVersionUID = 1L;
@XmlElement(name = "bar")
@XmlJavaTypeAdapter(DateAdapter.class)
@XmlSchemaType(name = "date")
private Date bar;
// getters/setters
}
這是日期適配器
public class DateAdapter extends XmlAdapter<String, Date>
{
@Override
public String marshal(Date date)
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(date);
}
@Override
public Date unmarshal(String date) throws ParseException
{
DateFormat df = new SimpleDateFormat("yyyy-MM-ddXXX");
return df.parse(date);
}
}
這是主要的,驗證模式:
public static void main(String[] args) throws JAXBException, SAXException
{
JAXBContext context = JAXBContext.newInstance(Foo.class);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(Foo.class.getResource("/foo.xsd"));
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(schema);
Foo foo = (Foo) unmarshaller.unmarshal(Foo.class.getResource("/foo.xml"));
System.out.println("unmarshalled: " + foo.getBar());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "foo.xsd");
marshaller.setSchema(schema);
marshaller.marshal(foo, System.out);
}
這是輸出,時區已被刪除,日期表示已明顯改變
unmarshalled: Tue Dec 31 19:00:00 CET 2013
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="foo.xsd">
<bar>2013-12-31</bar>
</foo>
也許這個日期表示更改不是您所期望的,但這不是JAXB關注的問題,所代表的日期沒有改變。
我忘了綁定反向生成Foo:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.0">
<jaxb:globalBindings>
<xjc:javaType name="java.util.Date" xmlType="xsd:date" adapter="aaa.DateAdapter" />
</jaxb:globalBindings>
</jaxb:bindings>
對不起,評論太久了......
我無法理解:
XmlGregorianCalendar
? marshal
/ unmarshal
( serialize
/ deserialize
serialize
)到完全相同的數據結構? 和
java.util.Date
marshal
/ unmarshal
應該總是涉及String
(至少對於XML) 然而
public class DateAdapter extends XmlAdapter<String, Date>
{
@Override
public String marshal(Date date)
{
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(date);
}
@Override
public Date unmarshal(String date) throws ParseException
{
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.parse(date);
}
public static void main(String[] args) throws ParseException
{
DateAdapter adapter = new DateAdapter();
String str = adapter.marshal(new Date());
System.out.println(str); // 16-dic-2013 10.02.09 --> to gmt
Date date = adapter.unmarshal(str);
System.out.println(date); // Mon Dec 16 11:02:09 CET 2013 --> correct, i'm gmt+1
}
}
在您的情況下,您必須以不同的方式指定java類型:
<jxb:javaType
name="javax.xml.datatype.XMLGregorianCalendar"
xmlType="xs:date"
printMethod="foo.bar.TimezoneRemoverAdapter.marshall"
parseMethod="foo.bar.TimezoneRemoverAdapter.unmarshall"
/>
它適用於我,我做了類似的更多適配器:
<jaxb:globalBindings>
<xjc:serializable uid="12343" />
<jaxb:javaType name="java.util.Date" xmlType="xs:date" printMethod="com.foo.DateAdapter.printDate" parseMethod="com.foo.DateAdapter.parseDate" />
<jaxb:javaType name="java.util.Date" xmlType="xs:dateTime" printMethod="com.foo.DateAdapter.printDate" parseMethod="com.foo.DateAdapter.parseDate" />
<jaxb:javaType name="java.util.Date" xmlType="xs:time" printMethod="com.foo.TimeAdapter.printTime" parseMethod="com.foo.TimeAdapter.parseTime" />
</jaxb:globalBindings>
我把上面的綁定作為globalBindings
在不同的文件.xjb
擴展,我用它無處不在,我需要它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.