杰克逊使一个 java 属性的两个 json 属性
jackson make two json attributes of one java attribute
我在休息时使用 jackson 有点不舒服 api。
我正在使用 jackson 序列化具有 java.time 中任何类型属性的对象,例如:
public class DomainObject{
public LocalDateTime start;
}
我可以使用 jackson 来产生这样的东西:
{
start: '2017-12-31 17:35:22'
}
我可以用它来制作这样的东西:
{
start: 102394580192345 //milliseconds
}
但我想要两者兼有,在 JS 中使用的毫秒数和使用 rest-api 的用户的字符串表示完全没有 js 前端。 (主要是我,用于调试)
那么有什么方法可以让杰克逊产生以下结果吗?
{
start: 102394580192345 //milliseconds
startString: '2017-12-31 17:35:22'
}
您可以编写一个自定义的 Jackson Serializer,然后必须在应用程序中注册它。之后,该数据类型的每次出现都将以这种方式序列化。即使要序列化的数据类型在另一个数据类型中。 (就像你的例子)
注意:请原谅我不要为 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 );
在此过程中,我建议创建一个 Producer ( CDI ),它将始终 return 一个默认添加此序列化程序的 objectMapper。但我会把这个任务留给你去研究;)
一种简单的方法是自己将字符串转换为额外的 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
我在休息时使用 jackson 有点不舒服 api。 我正在使用 jackson 序列化具有 java.time 中任何类型属性的对象,例如:
public class DomainObject{
public LocalDateTime start;
}
我可以使用 jackson 来产生这样的东西:
{
start: '2017-12-31 17:35:22'
}
我可以用它来制作这样的东西:
{
start: 102394580192345 //milliseconds
}
但我想要两者兼有,在 JS 中使用的毫秒数和使用 rest-api 的用户的字符串表示完全没有 js 前端。 (主要是我,用于调试)
那么有什么方法可以让杰克逊产生以下结果吗?
{
start: 102394580192345 //milliseconds
startString: '2017-12-31 17:35:22'
}
您可以编写一个自定义的 Jackson Serializer,然后必须在应用程序中注册它。之后,该数据类型的每次出现都将以这种方式序列化。即使要序列化的数据类型在另一个数据类型中。 (就像你的例子)
注意:请原谅我不要为 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 );
在此过程中,我建议创建一个 Producer ( CDI ),它将始终 return 一个默认添加此序列化程序的 objectMapper。但我会把这个任务留给你去研究;)
一种简单的方法是自己将字符串转换为额外的 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