2017-01-31 6 views
0

ジャージーを使用してWebアプリケーションを作成しています&ジャージー。私はホストされているAPIのResponse POJOを作った。私は以下のように、日付フィールドのためのカスタムジャクソンシリアライザを作った。カスタムjacksonシリアライザがgsonと連携していません

class A{ 
    LocalDateTime localDateTime = LocalDateTime.now(); 

    @JsonSerialize(using = JacksonSerializers.DateSecondsFromEpochUTCSerializer.class) 
    public LocalDateTime getLocalDateTime() { 
     return localDateTime; 
    } 

    public void setLocalDateTime(LocalDateTime localDateTime) { 
     this.localDateTime = localDateTime; 
    } 
} 

シリアライザは以下の通りです:

public class JacksonSerializers { 

@Component 
public static class DateSecondsFromEpochUTCSerializer extends JsonSerializer<LocalDateTime> { 

    @Override 
    public void serialize(LocalDateTime localDateTime, JsonGenerator gen, SerializerProvider provider) 
      throws IOException, JsonProcessingException { 
     gen.writeNumber(localDateTime.toEpochSecond(ZoneOffset.UTC)); 
    } 

} 

APIが呼び出されたときに上記のコードは正常に動作していると応答がエポック形式で日付が含まれています。

しかし、私がGSONライブラリを使ってクラスのJSONを作成しようとしているとき、上記のシリアライゼーションは機能しません。私は以下の誤った出力を取得しています:

System.out.print(new Gson().toJson(new A())); 

{"localDateTime":{"date":{"year":2017,"month":1,"day":31},"time":{"hour":12,"minute":55,"second":53,"nano":481000000}}} 

を与えるしかし、私は1485847871をしたいです。基本的には、どちらのフローでも、エポック時間でLocalDateTimeをシリアル化する必要があります。私はGSONを使ってやろうとしていますが、ハードコアの要件ではありません。両方の結果を達成するためのエレガントなソリューションがあれば可能です。

+3

「GSONを使用してLocalDateTimeをエポック形式にシリアル化するにはどうすればよいですか?なぜジャクソンの部分は、明らかに意図どおりに動作し、質問の一部でさえあるのでしょうか? – Henrik

+0

それは私が尋ねることではないからです。私はすでに、ジャージーを使ってLocalDateTimeをエポック形式に解析することができます。今、私はいくつかの他のタスクのために同じPOJOを使用しています。今回は、GSONを使用してPOJOをJSONにシリアル化しています。このメソッドは、Jacksonが作成しているのと同様の望ましい結果を生成しません。私は、両方の問題が同時に実行されなければならないので、両方の問題に対する共通の解決策を望んでいました。 –

+0

ObjectMapper(Jackson)は両方の問題を解決しました。後者は前提条件を持っていました。つまり、ジャクソンを使って以前のシリアライズを変更することはできませんでしたが、後者は –

答えて

-1

解決策が見つかりました:new ObjectMapper().writeValueAsString(new A())が動作しています。

+2

多分私はそれを得ることはありませんが、今あなたはGSONをもう使用していません...ジャクソンジャクソン。 –

+0

ええ、そうです。基本的に、私は両方のことをしたいと思っていました。 GSONはハードコア要件ではありませんでした。 –

+2

この場合、自分の答えを削除する必要があります(または少なくとも編集する必要があります)。非常に興味深い質問ですが、誰かが解決策を持っているかもしれません。 –

1

ジャクソンとGSONの両方で使用できる統合シリアライザを作成することは可能です。この線に沿って何か:

public class DateSecondsFromEpochUTCSerializer 
     extends com.fasterxml.jackson.databind.JsonSerializer<LocalDateTime> 
     implements com.google.gson.JsonSerializer<LocalDateTime> { 

    @Override 
    public void serialize(LocalDateTime localDateTime, JsonGenerator gen, SerializerProvider provider) throws IOException { 
     gen.writeNumber(convert(localDateTime)); 
    } 

    @Override 
    public JsonElement serialize(LocalDateTime ldt, Type type, JsonSerializationContext jsonSerializationContext) { 
     return new JsonPrimitive(convert(ldt)); 
    } 

    private long convert(LocalDateTime ldt) { 
     return ldt.toEpochSecond(ZoneOffset.UTC); 
    } 
} 

このようなあなたのGSONインスタンスでそれをインストールします。それは完全なので、あなたはまだGsonと罰金なら

Gson gson = new GsonBuilder() 
    .registerTypeAdapter(LocalDateTime.class, new DateSecondsFromEpochUTCSerializer()) 
    .create(); 
System.out.println(gson.toJson(LocalDateTime.now())); // Epoch 
0

を、ジャクソンを必要としないが導入されます別のライブラリは、カスタムGsonタイプのアダプタを使用することができます。

final class LocalDateTimeTypeAdapter 
     extends TypeAdapter<LocalDateTime> { 

    private static final TypeAdapter<LocalDateTime> localDateTimeTypeAdapter = new LocalDateTimeTypeAdapter(); 

    private LocalDateTimeTypeAdapter() { 
    } 

    static TypeAdapter<LocalDateTime> getLocalDateTimeTypeAdapter() { 
     return localDateTimeTypeAdapter; 
    } 

    @Override 
    @SuppressWarnings("resource") 
    public void write(final JsonWriter out, final LocalDateTime value) 
      throws IOException { 
     out.value(value.toEpochSecond(UTC)); 
    } 

    @Override 
    public LocalDateTime read(final JsonReader in) 
      throws IOException { 
     return Instant.ofEpochSecond(in.nextLong()).atZone(UTC).toLocalDateTime(); 
    } 

} 

これはJsonSerializer/JsonDeserializerペアをGsonに似ているが、それはトン以来、より効率的です後者は、JSONツリーをメモリに構築する必要がありますが、タイプアダプタはストリーミングの仕方で動作し、中間の状態をあまり蓄積しない値を生成する可能性があります。 { "のLocalDateTime":1485871467}

:それからちょうどあなたのGsonインスタンス設定:

final Gson gson = new GsonBuilder() 
     .registerTypeAdapter(LocalDateTime.class, getLocalDateTimeTypeAdapter()) 
     .create(); 
final String json = gson.toJson(new A()); 
out.println(json); 
final A a = gson.fromJson(json, A.class); 
out.println(a.localDateTime); 

をそして、それはのようなものを生成する
2017-01-31T14:04:27

をシリアライゼーションとデシリアライズの両方の場合は

です。

関連する問題