如何指定JAXB封送xsd:dateTime时使用的日期格式?

You*_* Fu 83 format datetime jaxb marshalling milliseconds

当JAXB将日期对象(XMLGregorianCalendar)编组到xsd:dateTime元素中时,如何指定生成的XML的格式?

例如:默认数据格式是使用<StartDate>2012-08-21T13:21:58.000Z</StartDate> 我需要的毫秒来省略毫秒. <StartDate>2012-08-21T13:21:58Z</StartDate>

如何指定我希望它使用的输出格式/日期格式?我正在使用javax.xml.datatype.DatatypeFactory创建XMLGregorianCalendar对象.

XMLGregorianCalendar xmlCal = datatypeFactory.newXMLGregorianCalendar(cal);
Run Code Online (Sandbox Code Playgroud)

bdo*_*han 121

您可以使用a XmlAdapter来自定义日期类型如何写入XML.

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class DateAdapter extends XmlAdapter<String, Date> {

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

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

    @Override
    public Date unmarshal(String v) throws Exception {
        synchronized (dateFormat) {
            return dateFormat.parse(v);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后使用@XmlJavaTypeAdapter注释指定XmlAdapter应该用于特定的字段/属性.

@XmlElement(name = "timestamp", required = true) 
@XmlJavaTypeAdapter(DateAdapter.class)
protected Date timestamp; 
Run Code Online (Sandbox Code Playgroud)

使用xjb绑定文件:

<jxb:javaType name="java.time.ZonedDateTime" 
              xmlType="xs:dateTime"

    parseMethod="my.package.DateAdapter.parseDateTime"
    printMethod="my.package.DateAdapter.formatDateTime" />
Run Code Online (Sandbox Code Playgroud)

将产生上述注释.

  • SDF不是线程保存 - > DateAdapter不是线程保存. (22认同)
  • 正如@PeterRader所提到的,SimpleDateFormat不是线程安全的 - 如果两个线程同时输入marshal或unmarshal,你可能会得到非常不可预测的结果.这在正常测试中很难重现,但在负载下可能会发生,并且诊断起来非常困难.最好使用marshal和unmarshal创建一个新的SimpleDateFormat(但如果需要,可以使用静态格式字符串). (8认同)
  • 由于关键块受“同步”保护,因此没有任何问题。如果进行多次调用,则会出现(性能)问题。 (3认同)
  • 感谢您的回答!是否可以通过 xsd 或绑定文件添加注释?我只找到了您经常引用的有关 bindings.xml 的博客条目,但我认为这涵盖了其他方面。 (2认同)

小智 16

我使用SimpleDateFormat来创建XMLGregorianCalendar,例如在这个例子中:

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

public static XMLGregorianCalendar getXmlDateTime(Date date) throws DatatypeConfigurationException {
    return DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(date));
}
Run Code Online (Sandbox Code Playgroud)

第一种方法创建XMLGregorianCalendar的实例,该实例由XML marshaller格式化为有效的xsd:date,第二种方法生成有效的xsd:dateTime.