你如何用JAXB编组XMLGregorianCalender?

时间:2017-08-16 04:53:59

标签: java xml jaxb

我试图写出XML格式的XMLGregorianCalender使用JAXB来创建XML Web服务请求。但它不会打印出来。

SELECT distinct u.id,
       u.name,
       ud.age,
       ud.about,
       ud.birth_date
       count(pf.viewer_id)
FROM users u
INNER JOIN user_details ud ON u.id = ud.user_id
INNER JOIN profile_views pf ON u.id = pf.user_id
group by u.id,
           u.name,
           ud.age,
           ud.about,
           ud.birth_date

在同一个班级的其他地方

    private static XMLGregorianCalendar getXmlDate() throws DatatypeConfigurationException {
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
    }

因此它调用ApplicationHeader类中生成的代码...

   try {
        applicationHeader.setApplicationDate(getXmlDate());
    } catch (DatatypeConfigurationException e1) {
        e1.printStackTrace();
    }

所以我希望得到像

这样的东西
    @XmlElement(name = "ApplicationDate", required = true)
    protected XMLGregorianCalendar applicationDate;

    public XMLGregorianCalendar getApplicationDate() {
        return applicationDate;
    }

    public void setApplicationDate(XMLGregorianCalendar value) {
        this.applicationDate = value;
    }
    ...

但我得到了

    <ApplicationDate>2009-03-13</ApplicationDate>

我做错了什么?

1 个答案:

答案 0 :(得分:1)

显然JAXB无法处理XMLGregorianCalender类型。所以我通过使用JAXB XmlAdapter 解决了这个问题,它基本上允许我们映射任何类型的类。哪里......

BoundType - 类型JAXB不知道如何处理。在本例中是XMLGregorianCalender。

ValueType - JAXB实际上知道如何处理的类型。在这种情况下,类型为String。

因此,在生成XML请求时,扩展XMLAdapter以将BoundType转换为ValueType。因此,我们实际上是在ValueType中创建类型的内存中表示。

所以代码如下,

public class DateAdapter extends XmlAdapter<String, XMLGregorianCalendar>  {

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    // Unmarshal by converting the value type to a bound type.
    @Override
    public XMLGregorianCalendar unmarshal(String v) throws Exception {
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(v);
    }

    // Marshal by converting the bound type to a value type.
    @Override
    public String marshal(XMLGregorianCalendar v) throws Exception {
        synchronized (dateFormat) {
            //return dateFormat.format(v);
            return specialFormatForXmlGregorianCalander(v);
        }
    }

    // Because you cannot format an XMLGregorianCalender typyou need to generate a GregorianCalender from it first  
    private String specialFormatForXmlGregorianCalander(XMLGregorianCalendar calander){
        // Convert from XMLGregorianCalander to GregorianCalander
        GregorianCalendar gCalender = calander.toGregorianCalendar();

        // Get the date
        java.util.Date date = gCalender.getTime();

        //define the type of calendar to be GegorianCalander
        dateFormat.setCalendar(gCalender);

        // Return the string version
        return dateFormat.format(date);
    }
}

所以现在在我的JAXB Generated类ApplicatioHeader中,我需要注释以告诉JAXB使用名为DateAdaptor的XMLAdaptor。

    @XmlElement(name = "ApplicationDate", required = true)
    @XmlJavaTypeAdapter(DateAdapter.class)
    protected XMLGregorianCalendar applicationDate;

重新运行我的代码

    <app1:ApplicationDate>2017-08-15</app1:ApplicationDate>