使用JAXB

时间:2018-07-30 21:55:32

标签: java date soap jaxb currency

我正在尝试对Java pojo进行umarshall xml响应。在使用jaxb进行编组时遇到日期和货币值问题

解组结果,货币字段值未映射(空)和日期字段被映射到某些数字(例如1503979200000)

有人可以让我知道我要去哪里了吗?预先感谢您的帮助。

下面是我的代码: 解组代码:        JAXBContext jc = JAXBContext.newInstance(Item.class);         Unmarshaller um = jc.createUnmarshaller();         项目输出=  (Item)um.unmarshal(soapMessage.getSOAPBody()。extractContentAsDocument());

Pojo:

@XmlRootElement( name = "item" )
@XmlAccessorType(XmlAccessType.FIELD)  

public class Item{

 @XmlElement( name = "bl" )
 @XmlJavaTypeAdapter(DateTimeAdapter.class)
 private Date docDate;

 @XmlElement( name = "sd" )
 @XmlJavaTypeAdapter(DateTimeAdapter.class)
 private Date dueDate;

 @XmlElement( name = "bu" )
 @XmlJavaTypeAdapter(DateTimeAdapter.class)
 private Date postingDate;

 @XmlElement( name = "wr" )
 @XmlJavaTypeAdapter(CurrencyAdapter.class)
 private Currency amount;

...

}

XML中的日期值格式为yyyy-MM-dd

解组后的结果: 量=空docDate = 1503979200000 dueDate = 1503979200000 postsDate = 1503979200000

1 个答案:

答案 0 :(得分:0)

tl; dr

  • 功能,不是错误。
  • 您的数字1_503_979_200_000L是从1970-01-01T00:00:00Z开始的毫秒数。

提示:

  • 使用 java.time 类代替旧的日期时间类。
  • 将日期时间值序列化为文本时,请使用 ISO 8601 格式。

从纪元开始计数

您的java.util.Date对象被序列化为自1970年1月1日世界标准时间(UTC)1970-01-01T00:00:00Z以来的epoch reference moment以来的毫秒数。有时称为Unix Time, or POSIX Time

java.time

您使用的java.util.Date类是与最早的Java版本捆绑在一起的可怕的旧日期时间类之一。不要使用这些类!多年前,它们被Java 8及更高版本中内置的 java.time 类所取代。

具体地说,DateInstant所代替。两者都表示UTC中的一个时刻,但是Instant解析为更精细的纳秒级而不是毫秒级。

long input = 1_503_979_200_000L;
Instant instant = Instant.ofEpochMilli( input  );
  

instant.toString():2017-08-29T04:00:00Z

根据the Answer上的my Question,JAXB尚未针对 java.time 更新。但是,可以使用适配器,例如this one

ISO 8601

ISO 8061标准定义了将日期时间值序列化为文本的实用格式。它们很容易用机器解析。跨文化的人类很容易阅读它们。

java.time 类在解析/生成字符串时默认使用这些格式。

示例应用

这是一个简单的小示例应用程序,用于演示如何使用 java.time Instant

我们通过Maven添加了JAXB adapters for Java 8 Date and Time API (JSR-310) types库。我们需要Instant的适配器,因为JAXB尚未针对 java.time 类型进行更新。希望如果我们看到Jakarta EE组织的迅速发展,就可以进行更新。

<dependency>
    <groupId>com.migesok</groupId>
    <artifactId>jaxb-java-time-adapters</artifactId>
    <version>1.1.3</version>
</dependency>

首先,我们简单的带有两个属性Eventwhen的小型业务对象类description

package com.basilbourque.example;

import com.migesok.jaxb.adapter.javatime.InstantXmlAdapter;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.time.Instant;

public class Event {

    private Instant when;
    private String description;

    // ---------------|  Constructors  |-------------------------

    public Event ( Instant when , String description ) {
        this.when = when;
        this.description = description;
    }

    // ---------------|  Accessors  |-------------------------

    @XmlJavaTypeAdapter ( InstantXmlAdapter.class )
    public Instant getWhen () {
        return when;
    }

    public void setWhen ( Instant when ) {
        this.when = when;
    }

    public String getDescription () {
        return description;
    }

    public void setDescription ( String description ) {
        this.description = description;
    }

    // ---------------|  Object  |-------------------------

    @Override
    public String toString () {
        return "Event{ " +
                "when=" + when +
                ", description='" + description + '\'' +
                " }";
    }
}

实例化业务对象。

Event e = new Event( Instant.now() , "Devoxx" );
System.out.println("e.toString(): " + e);
System.out.println(""); // blank line.
  

e.toString():事件{时间= 2018-07-31T04:03:43.113356Z,description ='Devoxx'}

运行我们的JAXB代码。

try {
    JAXBContext jc = JAXBContext.newInstance( Event.class );
    Marshaller marshaller = jc.createMarshaller();
    marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT , true );
    JAXBElement< Event > jaxbElement = new JAXBElement< Event >( new QName( "event" ) , Event.class , e );
    marshaller.marshal( jaxbElement , System.out );
} catch ( JAXBException e1 ) {
    e1.printStackTrace();
}

结果:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<event>
    <description>Devoxx</description>
    <when>2018-07-31T04:03:43.113356Z</when>
</event>

我们看到XML 2018-07-31T04:03:43.113356Z中使用了标准的ISO 8601格式。最后的Z表示UTC,发音为Zulu

1503979200000更具可读性!


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore