Джексон делает два атрибута json из одного атрибута java
У меня есть немного проблемы с комфортом, используя Джексон в API отдыха. Я использую Джексона для сериализации объекта, который имеет атрибуты любого типа в java.time, например:
public class DomainObject{
public LocalDateTime start;
}
Я могу использовать Джексона, чтобы произвести что-то вроде этого:
{
start: '2017-12-31 17:35:22'
}
И я могу использовать это, чтобы произвести что-то вроде этого:
{
start: 102394580192345 //milliseconds
}
Но я хотел бы иметь и миллисекунды для работы с JS, и представление String для пользователей, которые используют rest-api исключительно без js-frontend. (В основном я, для отладки)
Так есть ли способ заставить Джексона произвести следующее?
{
start: 102394580192345 //milliseconds
startString: '2017-12-31 17:35:22'
}
2 ответа
Вы можете написать собственный сериализатор Jackson, который затем должен быть зарегистрирован в приложении. После этого каждый экземпляр этого 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();
}
}
Затем он регистрируется для ObjectMapper of Jackson следующим образом:
objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule( "MyModule" );
module.addSerializer( ZonedDateTime.class, new ZonedDateTimeSerializer() );
objectMapper.registerModule( module );
В этом процессе я бы предложил создать A Producer ( CDI), который всегда будет возвращать objectMapper с этим сериализатором, добавленным по умолчанию. Но я оставлю эту задачу на ваше усмотрение;)
Простым способом было бы сделать преобразование строк самостоятельно как дополнительное поле 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