1

在休息 api 中使用杰克逊时,我遇到了一点舒适问题。我正在使用 jackson 序列化在 java.time 中具有任何类型属性的对象,例如:

public class DomainObject{
   public LocalDateTime start;
}

我可以使用杰克逊来制作这样的东西:

{
    start: '2017-12-31 17:35:22'
}

我可以用它来产生这样的东西:

{
    start: 102394580192345 //milliseconds
}

但我想同时拥有 JS 中的毫秒数和纯粹使用 rest-api 而没有 js-frontend 的用户的字符串表示。(主要是我,用于调试)

那么有什么办法可以让杰克逊产生以下内容?

{
    start: 102394580192345 //milliseconds
    startString: '2017-12-31 17:35:22'
}
4

2 回答 2

2

您可以编写一个自定义 Jackson Serializer,然后必须在应用程序中进行注册。之后,该 dataType 的每次出现都将以这种方式序列化。即使要序列化的数据类型在另一个数据类型中。(就像你的例子)

注意:请容忍我不要为 LocalDateTime 编写它,因为我在我的应用程序中为 ZonedDateTime 编写了它。根据您的需要重写它对您来说应该不是一项艰巨的任务。

public class ZonedDateTimeSerializer extends JsonSerializer<ZonedDateTime>
{

  @Override
  public void serialize( ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers ) throws IOException
  {
    gen.writeStartObject();
    gen.writeFieldName( "timestamp" );
    gen.writeString( Long.toString( value.toInstant().toEpochMilli() ) );
    gen.writeFieldName( "offset" );
    gen.writeString( value.getOffset().toString() );
    gen.writeFieldName( "zone" );
    gen.writeString( value.getZone().toString() );
    gen.writeFieldName( "ts" );
    gen.writeString( StringUtils.convertZonedDateTimeToISO8601String( value ) );
    gen.writeEndObject();
  }

}

然后像这样为 Jackson 的 ObjectMapper 注册它:

    objectMapper = new ObjectMapper();
    SimpleModule module = new SimpleModule( "MyModule" );
    module.addSerializer( ZonedDateTime.class, new ZonedDateTimeSerializer() );
    objectMapper.registerModule( module );

在这个过程中,我建议创建一个生产者( CDI ),它总是返回一个默认添加了这个序列化程序的 objectMapper。但我会把这项任务留给你去研究;)

于 2017-07-19T11:12:06.583 回答
2

一种简单的方法是自己将字符串转换为额外的 JSON 字段:

public class DomainObject {
   private LocalDateTime start;

   @JsonProperty("startString")
   public String formatStartDate() {
     // use a date formatter to format the date as string here
   }
}

Jackson 将start正常序列化,并且您添加了一个额外的 JSON 字段startString

于 2017-07-19T11:31:16.573 回答