Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何指定JAXB封送xsd:dateTime时使用的日期格式?_Datetime_Jaxb_Format_Marshalling_Milliseconds - Fatal编程技术网

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

如何指定JAXB封送xsd:dateTime时使用的日期格式?,datetime,jaxb,format,marshalling,milliseconds,Datetime,Jaxb,Format,Marshalling,Milliseconds,当JAXB将日期对象(XMLGregorianCalendar)封送到xsd:dateTime元素中时。如何指定生成的XML的格式 例如: 默认数据格式使用毫秒2012-08-21T13:21:58.000Z 我需要省略毫秒2012-08-21T13:21:58Z 如何指定要使用的输出表单/日期格式? 我正在使用javax.xml.datatype.DatatypeFactory创建XMLGregorianCalendar对象 XMLGregorianCalendar xmlCal = data

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

例如: 默认数据格式使用毫秒
2012-08-21T13:21:58.000Z
我需要省略毫秒<代码>2012-08-21T13:21:58Z

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

XMLGregorianCalendar xmlCal = datatypeFactory.newXMLGregorianCalendar(cal);

您可以使用
XmlAdapter
自定义日期类型写入XML的方式

package.com.example;
导入java.text.simpleDataFormat;
导入java.util.Date;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
公共类DateAdapter扩展了XmlAdapter{
私有最终SimpleDateFormat dateFormat=新SimpleDateFormat(“yyyy-MM-dd HH:MM:ss”);
@凌驾
公共字符串封送处理程序(日期v)引发异常{
已同步(日期格式){
返回日期格式。格式(v);
}
}
@凌驾
公共日期解组(字符串v)引发异常{
已同步(日期格式){
returndateformat.parse(v);
}
}
}
然后使用
@XmlJavaTypeAdapter
注释指定
XmlAdapter
应用于特定字段/属性

@xmlement(name=“timestamp”,required=true)
@XmlJavaTypeAdapter(DateAdapter.class)
受保护日期时间戳;
使用xjb绑定文件:

<xjc:javaType name="java.util.Date" xmlType="xs:dateTime"
        adapter="com.example.DateAdapter"/>

将生成上述注释。

(通过最终添加
xjc
名称空间:
xmlns:xjc=”http://java.sun.com/xml/ns/jaxb/xjc“

我使用SimpleDataFormat创建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));
}

第一个方法创建XMLGregorianCalendar的实例,该实例由XML封送处理程序格式化为有效的xsd:date,第二个方法生成有效的xsd:dateTime。

对我来说非常简单。在java中格式化用于编组的XMLGregorianCalendar

我只是以良好的格式创建数据。将调用
toString
,以产生良好的结果

public static final XMLGregorianCalendar getDate(Date d) {
    try {
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd").format(d));
    } catch (DatatypeConfigurationException e) {
        return null;
    }
}

公共类DateAdapter扩展了XmlAdapter{
私有静态最终线程本地日期格式
=新线程本地(){
@凌驾
受保护的日期格式初始值(){
返回新的SimpleDataFormat(“yyyy-MM-dd HH:MM:ss”);
}
}
@凌驾
公共日期解组(字符串v)引发异常{
return dateFormat.get().parse(v);
}
@凌驾
公共字符串封送处理程序(日期v)引发异常{
return dateFormat.get().format(v);
}
}
用法:

import com.company.LocalDateAdapter.yyyyMMdd;
...

@XmlElement(name = "PROC-DATE")
@XmlJavaTypeAdapter(yyyyMMdd.class)
private LocalDate processingDate;
LocalDateAdapter

import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {

    public static final class yyyyMMdd extends LocalDateAdapter {
        public yyyyMMdd() {
            super("yyyyMMdd");
        }
    }

    public static final class yyyy_MM_dd extends LocalDateAdapter {
        public yyyy_MM_dd() {
            super("yyyy-MM-dd");
        }
    }

    private final DateTimeFormatter formatter;

    public LocalDateAdapter(String pattern) {
        formatter = DateTimeFormat.forPattern(pattern);
    }

    @Override
    public String marshal(LocalDate date) throws Exception {
        return formatter.print(date);
    }

    @Override
    public LocalDate unmarshal(String date) throws Exception {
        return formatter.parseLocalDate(date);
    }
}
import javax.xml.bind.annotation.adapters.XmlAdapter;
导入org.joda.time.LocalDate;
导入org.joda.time.format.DateTimeFormat;
导入org.joda.time.format.DateTimeFormatter;
公共类LocalDateAdapter扩展了XmlAdapter{
公共静态最终类yyyyMMdd扩展了LocalDateAdapter{
公共yyyyMMdd(){
超级(“yyyyMMdd”);
}
}
公共静态最终类yyyy\u MM\u dd扩展LocalDateAdapter{
公共年/月/日(){
超级(“yyyy-MM-dd”);
}
}
专用最终日期时间格式化程序;
公共LocalDateAdapter(字符串模式){
格式化程序=DateTimeFormat.forPattern(模式);
}
@凌驾
公共字符串封送处理程序(LocalDate)引发异常{
返回格式化程序。打印(日期);
}
@凌驾
公共LocalDate解组(字符串日期)引发异常{
返回格式化程序.parseLocalDate(日期);
}
}

谢谢您的回答!是否可以通过xsd或绑定文件添加注释?我只找到了您经常引用的关于bindings.xml的博客文章,但我认为这涉及到了其他方面。正如@PeterRader提到的,SimpleDateFormat不是线程安全的-如果两个线程同时进入封送或解封,您可能会得到非常不可预知的结果。这将很难在正常测试中重现,但在负载下可能会发生,并且极难诊断。最好使用封送和反封送创建一个新的SimpleDataFormat(但如果需要,可以使用静态格式字符串)。然而,我发现
类有两个同名的属性“timeSeries”
错误-这是通过将注释放在getter而不是成员级别来解决的。(感谢@megathor from)@gordon613-本文将提供一些有关注释放置位置的附加信息:由于关键块受“synchronized”保护,因此没有任何问题。如果打了多个电话,就会出现(性能)问题。
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {

    public static final class yyyyMMdd extends LocalDateAdapter {
        public yyyyMMdd() {
            super("yyyyMMdd");
        }
    }

    public static final class yyyy_MM_dd extends LocalDateAdapter {
        public yyyy_MM_dd() {
            super("yyyy-MM-dd");
        }
    }

    private final DateTimeFormatter formatter;

    public LocalDateAdapter(String pattern) {
        formatter = DateTimeFormat.forPattern(pattern);
    }

    @Override
    public String marshal(LocalDate date) throws Exception {
        return formatter.print(date);
    }

    @Override
    public LocalDate unmarshal(String date) throws Exception {
        return formatter.parseLocalDate(date);
    }
}