Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.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
Java 自定义jackson序列化程序不与gson一起工作_Java_Json_Serialization_Jackson_Gson - Fatal编程技术网

Java 自定义jackson序列化程序不与gson一起工作

Java 自定义jackson序列化程序不与gson一起工作,java,json,serialization,jackson,gson,Java,Json,Serialization,Jackson,Gson,我正在使用Jackson&Jersey制作一个web应用程序。我已经对托管的API做出了POJO响应。我为日期字段制作了一个定制的Jackson序列化程序,如下所示 class A{ LocalDateTime localDateTime = LocalDateTime.now(); @JsonSerialize(using = JacksonSerializers.DateSecondsFromEpochUTCSerializer.class) public Loca

我正在使用Jackson&Jersey制作一个web应用程序。我已经对托管的API做出了POJO响应。我为日期字段制作了一个定制的Jackson序列化程序,如下所示

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));
    }

}
给予

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

但我要1485847871。基本上,我想在两个流中序列化纪元时间中的LocalDateTime。我现在正尝试使用GSON,但这不是硬核要求。任何优雅的解决方案都可以实现这两个结果。

可以创建一个统一的序列化程序,您可以将其用于Jackson和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仍然满意,并且不需要引入Jackson,因为它是一个完全不同的库,那么您可以使用自定义Gson类型适配器:

最终类LocalDateTimeTypeAdapter 扩展类型适配器{ 私有静态最终类型适配器localDateTimeTypeAdapter=新的localDateTimeTypeAdapter; 专用LocalDateTimeTypeAdapter{ } 静态类型适配器getLocalDateTimeTypeAdapter{ 返回localDateTimeTypeAdapter; } @凌驾 @抑制警告资源 public void writefinal JsonWriter out,最终LocalDateTime值 抛出IOException{ out.valuevalue.toEpochSecondUTC; } @凌驾 中的公共LocalDateTime readfinal JsonReader 抛出IOException{ 返回Instant.ofEpochSecondin.nextLong.atZoneUTC.toLocalDateTime; } } 这类似于Gson的JsonSerializer/JsonDeserializer对,但效率更高,因为后者需要在内存中构建JSON树,而类型适配器以流式方式工作,可能生成的值不会太多地累积中间状态。然后只需配置您的Gson实例:

最终Gson Gson=新的GsonBuilder .registerTypeAdapterLocalDateTime.class,getLocalDateTimeTypeAdapter 创造 最后一个字符串json=gson.toJsonnew A; out.printlnjson; 最终A=gson.fromJsonjson,A.class; out.printlna.localDateTime; 它会产生类似于:

{localDateTime:1485871467} 2017-01-31T14:04:27


用于序列化和反序列化。

适合我的解决方案:

new ObjectMapper().writeValueAsString(new A())

这个问题基本上不能归结为如何使用GSON将LocalDateTime序列化为epoch格式吗??为什么杰克逊的部分,这显然是有意的,甚至是问题的一部分?因为这不是我想问的。我已经能够使用Jackson在Jersey中将LocalDateTime解析为epoch格式。现在,我在其他任务中使用相同的POJO,这次我使用GSON将POJO序列化为JSON,这个方法不会产生类似Jackson所产生的预期结果。我想要两个问题的通用解决方案,因为这两个问题必须同时运行。ObjectMapper Jackson解决了这两个问题。后一部分有一个先决条件,即早期使用Jackson的序列化无法更改,但后一部分可以更改,如果有人使用Gson解决方案进行应答,那么这也将是该问题的正确答案。一个问题可以有多种解决方案:
Gson gson = new GsonBuilder()
    .registerTypeAdapter(LocalDateTime.class, new DateSecondsFromEpochUTCSerializer())
    .create();
System.out.println(gson.toJson(LocalDateTime.now())); // Epoch
new ObjectMapper().writeValueAsString(new A())