diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReader.java b/core/src/main/java/com/alibaba/fastjson2/JSONReader.java index 3f3fac5f3b..05f260a5b0 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReader.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReader.java @@ -1445,6 +1445,11 @@ public ZonedDateTime readZonedDateTime() { return ZonedDateTime.parse(str); } + + if (isNull()) { + readNull(); + return null; + } throw new JSONException("TODO : " + ch); } diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java index 1494de982c..b93af658be 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java @@ -5789,7 +5789,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } if (m0 >= '0' && m0 <= '9' @@ -5797,7 +5798,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { month = (m0 - '0') * 10 + (m1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int dom; @@ -5806,7 +5808,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { dom = (d0 - '0') * 10 + (d1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int hour; @@ -5815,7 +5818,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { hour = (h0 - '0') * 10 + (h1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int minute; @@ -5824,7 +5828,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { minute = (i0 - '0') * 10 + (i1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int second; @@ -5833,7 +5838,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { second = (s0 - '0') * 10 + (s1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } LocalDate localDate; @@ -5871,7 +5877,8 @@ public final OffsetDateTime readOffsetDateTime() { } } } - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } @Override diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java index dcced30bff..ba651553dd 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java @@ -7024,7 +7024,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } if (m0 >= '0' && m0 <= '9' @@ -7032,7 +7033,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { month = (m0 - '0') * 10 + (m1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int dom; @@ -7041,7 +7043,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { dom = (d0 - '0') * 10 + (d1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int hour; @@ -7050,7 +7053,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { hour = (h0 - '0') * 10 + (h1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int minute; @@ -7059,7 +7063,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { minute = (i0 - '0') * 10 + (i1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } int second; @@ -7068,7 +7073,8 @@ public final OffsetDateTime readOffsetDateTime() { ) { second = (s0 - '0') * 10 + (s1 - '0'); } else { - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } LocalDate localDate; @@ -7106,7 +7112,8 @@ public final OffsetDateTime readOffsetDateTime() { } } } - return readZonedDateTime().toOffsetDateTime(); + ZonedDateTime zdt = readZonedDateTime(); + return zdt == null ? null : zdt.toOffsetDateTime(); } @Override diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_1800/Issue1861.java b/core/src/test/java/com/alibaba/fastjson2/issues_1800/Issue1861.java new file mode 100644 index 0000000000..bd902a9b5a --- /dev/null +++ b/core/src/test/java/com/alibaba/fastjson2/issues_1800/Issue1861.java @@ -0,0 +1,59 @@ +package com.alibaba.fastjson2.issues_1800; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONWriter; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.junit.jupiter.api.Test; + +import javax.validation.Valid; +import java.time.OffsetDateTime; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +public class Issue1861 { + @Test + public void test() { + String json = "{\"myData1\":{\"myData2\":{\"key\":{\"startTime\":null}}}}"; + MyData data = JSON.parseObject(json, MyData.class); + assertEquals(json, JSON.toJSONString(data, JSONWriter.Feature.WriteNulls)); + } + + public class MyData { + private MyData1 myData1; + + public MyData1 getMyData1() { + return myData1; + } + + public void setMyData1(MyData1 myData1) { + this.myData1 = myData1; + } + } + + public class MyData1 { + @JsonProperty("myData2") + private @Valid Map myData2 = null; + + public Map getMyData2() { + return myData2; + } + + public void setMyData2(Map myData2) { + this.myData2 = myData2; + } + } + + public class MyData2 { + @JsonProperty("startTime") + private OffsetDateTime startTime; + + public OffsetDateTime getStartTime() { + return startTime; + } + + public void setStartTime(OffsetDateTime startTime) { + this.startTime = startTime; + } + } +}