web-dev-qa-db-ja.com

JSONで日付をシリアル化REST WebサービスをISO-8601文字列として

JBoss AS 7.1を使用するJAX-RSアプリケーションがあり、日付(Java.util.Date)を含むJSONおよびXMLオブジェクトをPOST/GETします。

@XmlRootElement
@XmlAccessorType(XmlAccessField.FIELD)
public class MyObject implements Serializable
{
    @XmlSchemaType(name = "dateTime")
    private Date date;
    ...
}

Getメソッドで@Produce( "application/xml")を使用すると、オブジェクトはXMLとしてシリアル化され、日付はISO-8601文字列に変換されます(例: "2012-12-10T14:50:12.123 + 02:00" )。

ただし、getメソッドで@Produce( "application/json")を使用すると、JSONオブジェクトの日付はISO-8601文字列ではなくタイムスタンプ(たとえば、「1355147452530」)になります。

日付をJSON形式でタイムスタンプではなくISO-8601文字列としてシリアル化するようにJAX-RS実装(RESTEasy)を構成するにはどうすればよいですか?

ご回答ありがとうございます。

注:カスタムJAX-RSプロバイダーを使用してDatesのJSONシリアル化も実行しようとしました

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class CustomJsonDateProvider implements MessageBodyWriter<Date>
{
    ...
}

このプロバイダーは、JBossの起動時にRESTeasyによって登録されているようです。

[org.jboss.jaxrs] Adding JAX-RS provider classes: package.CustomJsonDateProvider
...
[org.jboss.resteasy.cdi.CdiInjectorFactory] No CDI beans found for class package.CustomJsonDateProvider. Using default ConstructorInjector.

しかし、それは決して使用されません!

20
Zlika

あなたのjsonパーサーはジャクソンだと思います。試してみてください。

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd,HH:00", timezone="CET")
public Date date;

(Jackson 2.0以降)

11
Dan

デフォルトのJBossパーサーはJettisonですが、日付形式を変更できませんでした。そこで、Jacksonに切り替えて、プロジェクトに次のクラスを追加して構成しました。

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonConfig implements ContextResolver<ObjectMapper>
{
    private final ObjectMapper objectMapper;

    public JacksonConfig()
    {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESPAMPS, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> objectType)
    {
        return objectMapper;
    }
}
2
Zlika

大声で叫んでごめんなさい-私はここで答えを見つけました

http://wiki.fasterxml.com/JacksonFAQDateHandling

ここに

http://wiki.fasterxml.com/JacksonFAQ#Serializing_Dates

ここに

http://wiki.fasterxml.com/JacksonHowToCustomSerializers

ここに

http://jackson.codehaus.org/1.1.2/javadoc/org/codehaus/jackson/map/util/StdDateFormat.html

@JsonSerialize(using = ...)を使用する方法:

public class JsonStdDateSerializer
extends JsonSerializer<Date> {

  private static final DateFormat iso8601Format =
    StdDateFormat.getBlueprintISO8601Format();

  @Override
  public void serialize(
    Date date, JsonGenerator jgen, SerializerProvider provider)
  throws IOException, JsonProcessingException {

    // clone because DateFormat is not thread-safe
    DateFormat myformat = (DateFormat) iso8601Format.clone();
    String formattedDate = myformat.format(date);
    jgen.writeString(formattedDate);
  }
}

Soap/XMLで使用されるのと同じSerializerを宣言します。

@XmlElement(name = "prealert_date")
@XmlSchemaType(name = "dateTime")
@JsonSerialize(using = XMLGregorianCalendarSerializer.class)
protected XMLGregorianCalendar prealertDate;
0