栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

杰克逊:解析自定义偏移日期时间

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

杰克逊:解析自定义偏移日期时间

您必须告诉杰克逊日期是什么格式。基本上,您

year-month-day
紧接着是
hour:minute:second.microseconds
和带有2个数字的偏移量(
+02
)。因此,您的模式将是:

@JsonProperty("timestamp")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSSSSx")private OffsetDateTime timestamp;

查看所有日期/时间模式以获得更详细的说明。


如果要在中保留相同的offset(

+02
OffsetDateTime
,请不要忘记将
DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
选项调整为
false

如果将此选项设置为

true
(在我的测试中),结果将转换为UTC(但实际上将转换为Jackson中配置的任何时区):

2017-09-17T11:45:42.710576Z

如果将设置为

false
,则会保留输入中使用的偏移量:

2017-09-17T13:45:42.710576 + 02:00


上面的代码仅在小数点后6位有效。但是,如果此数量有所变化,则可以使用以分隔的可选模式

[]

示例:如果输入可以有6或3个十进制数字,则可以使用

pattern = "yyyy-MM-ddHH:mm:ss.[SSSSSS][SSS]x"
。可选部分,
[SSSSSS]
[SSS]
告诉解析器考虑6位或3位数字。

可选模式的问题在于,在序列化时,它会打印所有模式(因此它将打印秒的小数两次:6位 3位)。


另一种选择是创建自定义的序列化器和反序列化器(通过扩展

com.fasterxml.jackson.databind.JsonSerializer
com.fasterxml.jackson.databind.JsonDeserializer
):

public class CustomDeserializer extends JsonDeserializer<OffsetDateTime> {    private DateTimeFormatter formatter;    public CustomDeserializer(DateTimeFormatter formatter) {        this.formatter = formatter;    }    @Override    public OffsetDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {        return OffsetDateTime.parse(parser.getText(), this.formatter);    }}public class CustomSerializer extends JsonSerializer<OffsetDateTime> {    private DateTimeFormatter formatter;    public CustomSerializer(DateTimeFormatter formatter) {        this.formatter = formatter;    }    @Override    public void serialize(OffsetDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException {        gen.writeString(value.format(this.formatter));    }}

然后,您可以在中注册

JavaTimeModule
。如何配置它取决于您所使用的环境(例如:在Spring中,您可以在xml文件中进行配置)。我将以编程方式作为示例。

首先,我使用来创建格式化程序

java.time.format.DateTimeFormatterBuilder

DateTimeFormatter formatter = new DateTimeFormatterBuilder()    // date/time    .appendPattern("yyyy-MM-dd HH:mm:ss")    // optional fraction of seconds (from 0 to 9 digits)    .optionalStart().appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true).optionalEnd()    // offset    .appendPattern("x")    // create formatter    .toFormatter();

此格式化程序接受0到9位数字的可选秒数。然后,我使用上面的自定义类并在中注册它们

ObjectMapper

// set formatter in the module and register in object mapperObjectMapper mapper = new ObjectMapper();mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);JavaTimeModule module = new JavaTimeModule();module.addSerializer(OffsetDateTime.class, new CustomSerializer(formatter));module.addDeserializer(OffsetDateTime.class, new CustomDeserializer(formatter));mapper.registerModule(module);

我还

@JsonFormat
从字段中删除了注释:

@JsonProperty("timestamp")private OffsetDateTime timestamp;

现在,它接受的值

2017-09-17 13:45:42+02
(不包括秒)和
2017-09-1713:45:42.71014+02
(5个十进制数字)。它可以解析0到9个十进制数字(9是API支持的最大值),并且在序列化时打印完全相同的数量。


上面的替代方法非常灵活,因为它允许在自定义类中设置格式化程序。但是,它还会为所有

OffsetDateTime
字段设置序列化和反序列化。

如果您不想这样做,还可以使用固定的格式化程序创建一个类:

static class CustomDeserializer extends JsonDeserializer<OffsetDateTime> {    private DateTimeFormatter formatter = // create formatter as above    // deserialize method is the same}static class CustomSerializer extends JsonSerializer<OffsetDateTime> {    private DateTimeFormatter formatter = // create formatter as above    // serialize method is the same}

然后,您可以使用注释

com.fasterxml.jackson.databind.annotation.JsonSerialize
和将这些仅添加到所需的字段中
com.fasterxml.jackson.databind.annotation.JsonDeserialize

@JsonProperty("timestamp")@JsonSerialize(using = CustomSerializer.class)@JsonDeserialize(using = CustomDeserializer.class)private OffsetDateTime timestamp;

这样,您无需在模块中注册自定义序列化程序,只有注释字段将使用自定义类(其他

OffsetDateTime
字段将使用默认设置)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/508552.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号