jackson制作一个java属性的两个json属性

时间:2017-07-19 11:07:09

标签: java json jackson jackson-modules jackson2

我在休息时使用杰克逊有一点舒适的问题。 我正在使用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'
}

2 个答案:

答案 0 :(得分:2)

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

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

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

}

然后注册为杰克逊的ObjectMapper:

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

在此过程中,我建议创建一个生产者(CDI),它将始终返回一个objectMapper,默认情况下会添加此序列化程序。但我会把这个任务留给你研究;)

答案 1 :(得分:2)

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

public class DomainObject {
   private LocalDateTime start;

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

杰克逊将正常序列化start,并且您添加了额外的JSON字段startString