5 回答

TA貢獻1712條經驗 獲得超3個贊
我只能控制ObjectMapper. 是否有任何可能的配置可以使這項工作?
只要您對時間和時區的默認值感到滿意,就可以使用自定義反序列化器解決它:
public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
@Override
public ZonedDateTime deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException {
LocalDate localDate = LocalDate.parse(
jsonParser.getText(),
DateTimeFormatter.ISO_LOCAL_DATE);
return localDate.atStartOfDay(ZoneOffset.UTC);
}
}
然后將其添加到模塊并將模塊注冊到您的ObjectMapper實例:
SimpleModule module = new SimpleModule();
module.addDeserializer(ZonedDateTime.class, new ZonedDateTimeDeserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
如果將反序列化器添加到模塊中不適合您(從某種意義上說,此配置將應用于其他ZonedDateTime實例),那么您可以依靠混合來定義反序列化器將應用于哪些字段。首先定義一個mix-in接口,如下圖:
public interface MarkdownMixIn {
@JsonDeserialize(using = ZonedDateTimeDeserializer.class)
ZonedDateTime getDate();
}
然后將混合接口綁定到所需的類:
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Markdown.class, MarkdownMixIn.class);

TA貢獻1757條經驗 獲得超7個贊
問題:我想將日期從 json 解析為 java LocalDateTime/ZonedDateTime 對象。ZonedDateTimeSerializer 存在但 ZonedDateTimeDeserializer 不存在。因此,為什么我創建了一個自定義 ZonedDateTimeDeserializer。
? public static final String ZONED_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSz";?
? @Getter
? @Setter
? @JsonSerialize(using = ZonedDateTimeSerializer.class)
? @JsonDeserialize(using = ZonedDateTimeDeserializer.class) // Doesn't exist, So I created a custom ZonedDateDeserializer utility class.
? @JsonFormat(pattern = ZONED_DATE_TIME_FORMAT)
? @JsonProperty("lastUpdated")
? private ZonedDateTime lastUpdated;
解決方案:我最終得到了更簡單、更少的代碼行。
用于反序列化ZonedDateTime的實用程序類:
/**
?* Custom {@link ZonedDateTime} deserializer.
?*
?* @param jsonParser? ? ? ? ? ? ?for extracting the date in {@link String} format.
?* @param deserializationContext for the process of deserialization a single root-level value.
?* @return {@link ZonedDateTime} object of the date.
?* @throws IOException throws I/O exceptions.
?*/
public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
? ? @Override
? ? public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
? ? ? ? ? ? throws IOException {
? ? ? ? return ZonedDateTime.parse(jsonParser.getText(), DateTimeFormatter.ofPattern(ZONED_DATE_TIME_FORMAT));
? ? }
}
如果您改用LocalDateTime怎么辦。在那種情況下,它甚至更容易,反序列化器和序列化器類都已經提供給我們了。不需要上面定義的自定義實用程序類:
? @Getter
? @Setter
? @JsonSerialize(using = LocalDateSerializer.class)
? @JsonDeserialize(using = LocalDateTimeDeserializer.class)
? @JsonFormat(pattern = ZONED_DATE_TIME_FORMAT) //Specify the format you want: "yyyy-MM-dd'T'HH:mm:ss.SSS"
? @JsonProperty("created")
? private LocalDateTime created;
關鍵詞:json格式 localDateTime zonedDateTime

TA貢獻1786條經驗 獲得超11個贊
不幸的是,默認情況下您不能反序列化為String Object格式ZonedDateTime。但是您可以通過兩種方式克服這個問題。
方式01
ZonedDateTime將類型更改為LocalDate在您的類中鍵入POJO并將值作為字符串傳遞03-06-2012
方式02
但是如果您必須使用時區存儲日期和時間,那么您必須執行以下方法來克服
步驟01
ZonedDateTime使用 DateTimeFormat創建反序列化類
public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
@Override
public ZonedDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss z");
LocalDate localDate = LocalDate.parse(p.getText(),dateTimeFormatter);
return localDate.atStartOfDay(ZoneOffset.UTC);
}
}
步驟02
@JsonDeserialize在方法級別注釋的支持下,您必須在 POJO 類中將反序列化類與受影響的字段一起使用。
@JsonDeserialize(using = ZonedDateTimeDeserializer.class)
private ZonedDateTime startDate;
步驟03
以 ZonedDateTimeDeserializer 類給出的上述格式將值作為字符串傳遞
"startDate" : "09-03-2003 10:15:00 Europe/Paris"

TA貢獻1900條經驗 獲得超5個贊
遺憾的是,如果不將 POJO 的類型更改為 LocalDate,那將很困難。
我能想到的最接近的解決方案是為杰克遜寫一個習慣JsonDeserializer
,這絕對不是那種事情的好習慣。

TA貢獻1876條經驗 獲得超6個贊
您可以編寫自己的反序列化器,如@cassiomolin答案中所示。但也有另一種選擇。在堆棧跟蹤中,我們有DeserializationContext.weirdStringException方法允許我們提供DeserializationProblemHandler處理奇怪字符串值的方法。請參閱以下示例:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
public class AppJson {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
// override default time zone if needed
mapper.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
mapper.registerModule(new JavaTimeModule());
mapper.addHandler(new DeserializationProblemHandler() {
@Override
public Object handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType,
String valueToConvert, String failureMsg) {
LocalDate date = LocalDate.parse(valueToConvert, DateTimeFormatter.ISO_DATE);
return date.atStartOfDay(ctxt.getTimeZone().toZoneId());
}
});
String json = "{\"startDate\": \"2019-07-25\"}";
Markdown markdown = mapper.readValue(json, Markdown.class);
System.out.println(markdown);
}
}
上面的代碼打?。?/p>
Markdown{startDate=2019-07-25T00:00-07:00[America/Los_Angeles]}
添加回答
舉報