diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReader.java b/core/src/main/java/com/alibaba/fastjson2/JSONReader.java index 8efc62b18f..7afbee496d 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReader.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReader.java @@ -344,7 +344,7 @@ public boolean nextIfObjectStart() { return true; } - public abstract boolean nextIfEmptyString(); + public abstract boolean nextIfNullOrEmptyString(); public boolean nextIfObjectEnd() { if (this.ch != '}') { diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderASCII.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderASCII.java index e8e780144b..95eb376f9e 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderASCII.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderASCII.java @@ -72,8 +72,13 @@ public boolean nextIfMatch(char ch) { } @Override - public boolean nextIfEmptyString() { + public boolean nextIfNullOrEmptyString() { final char first = this.ch; + if (first == 'n' && offset + 2 < end && bytes[offset] == 'u') { + this.readNull(); + return true; + } + if ((first != '"' && first != '\'') || offset >= end || bytes[offset] != first) { return false; } diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java index 73057a2c0d..48f1ea8c70 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java @@ -190,7 +190,12 @@ public final boolean nextIfObjectEnd() { } @Override - public final boolean nextIfEmptyString() { + public final boolean nextIfNullOrEmptyString() { + if (bytes[offset] == BC_NULL) { + offset++; + return true; + } + if (bytes[offset] != BC_STR_ASCII_FIX_MIN) { return false; } diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java index 48d4362e71..8800d4c51b 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java @@ -499,8 +499,13 @@ public boolean nextIfMatch(char ch) { } @Override - public boolean nextIfEmptyString() { + public boolean nextIfNullOrEmptyString() { final char first = this.ch; + if (first == 'n' && offset + 2 < end && chars[offset] == 'u') { + this.readNull(); + return true; + } + if ((first != '"' && first != '\'') || offset >= end || chars[offset] != first) { return false; } diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java index 9237dc15d1..0a08b71c87 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java @@ -7159,8 +7159,13 @@ public String readPattern() { } @Override - public boolean nextIfEmptyString() { + public boolean nextIfNullOrEmptyString() { final char first = this.ch; + if (first == 'n' && offset + 2 < end && bytes[offset] == 'u') { + this.readNull(); + return true; + } + if ((first != '"' && first != '\'') || offset >= end || this.bytes[offset] != first) { return false; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderImplDate.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderImplDate.java index 80acfc1711..e838528aa1 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderImplDate.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderImplDate.java @@ -264,7 +264,7 @@ public void readFieldValue(JSONReader jsonReader, T object) { } fieldValue = new java.util.Date(millis); } - } else if (jsonReader.nextIfEmptyString()) { + } else if (jsonReader.nextIfNullOrEmptyString()) { fieldValue = null; } else { long millis = jsonReader.readMillisFromString(); diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectArrayReaderMultiType.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectArrayReaderMultiType.java index 99c8672cfb..48dc05816a 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectArrayReaderMultiType.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectArrayReaderMultiType.java @@ -36,7 +36,7 @@ public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName return readJSONBObject(jsonReader, fieldType, fieldName, 0); } - if (jsonReader.readIfNull() || jsonReader.nextIfEmptyString()) { + if (jsonReader.nextIfNullOrEmptyString()) { return null; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReader1.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReader1.java index ae4dfb87ae..c065e0c2fa 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReader1.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReader1.java @@ -210,7 +210,7 @@ public T readObject(JSONReader jsonReader, Type fieldType, Object fieldName, lon return readJSONBObject(jsonReader, fieldType, fieldName, 0); } - if (jsonReader.nextIfNull() || jsonReader.nextIfEmptyString()) { + if (jsonReader.nextIfNullOrEmptyString()) { return null; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBean.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBean.java index 2458a0c9d2..1b820ad486 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBean.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBean.java @@ -159,19 +159,11 @@ protected void initDefaultValue(T object) { } public void readObject(JSONReader jsonReader, Object object, long features) { - if (jsonReader.isJSONB()) { -// return readJSONBObject(jsonReader, features); - } - if (jsonReader.nextIfNull()) { jsonReader.nextIfMatch(','); return; } - if (jsonReader.isArray() && jsonReader.isSupportBeanArray(getFeatures() | features)) { -// return readArrayMappingObject(jsonReader); - } - boolean objectStart = jsonReader.nextIfMatch('{'); if (!objectStart) { throw new JSONException(jsonReader.info()); @@ -210,7 +202,7 @@ public T readObject(JSONReader jsonReader, Type fieldType, Object fieldName, lon return readJSONBObject(jsonReader, fieldType, fieldName, features); } - if (jsonReader.nextIfNull()) { + if (jsonReader.nextIfNullOrEmptyString()) { jsonReader.nextIfMatch(','); return null; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderCreatorASM.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderCreatorASM.java index 6f99d7f369..f554a823a7 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderCreatorASM.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderCreatorASM.java @@ -1554,7 +1554,7 @@ private void genMethodReadObject( mw.visitJumpInsn(Opcodes.IFNE, notNull_); mw.visitVarInsn(Opcodes.ALOAD, JSON_READER); - mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_JSON_READER, "nextIfNull", "()Z", false); + mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_JSON_READER, "nextIfNullOrEmptyString", "()Z", false); mw.visitJumpInsn(Opcodes.IFEQ, notNull_); mw.visitInsn(Opcodes.ACONST_NULL); @@ -2151,10 +2151,10 @@ private int genReadFieldValue( mw.visitJumpInsn(Opcodes.GOTO, loadList_); } else if (itemType instanceof Class) { mw.visitVarInsn(Opcodes.ALOAD, JSON_READER); - mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_JSON_READER, "nextIfEmptyString", "()Z", false); + mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_JSON_READER, "nextIfNullOrEmptyString", "()Z", false); mw.visitJumpInsn(Opcodes.IFNE, loadNull_); - // nextIfEmptyString + // nextIfNullOrEmptyString mw.visitTypeInsn(Opcodes.NEW, LIST_TYPE); mw.visitInsn(Opcodes.DUP); if (initCapacity) { diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderException.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderException.java index ad9a650e07..3df3b53aef 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderException.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderException.java @@ -120,7 +120,7 @@ protected ObjectReaderException( public T readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) { boolean objectStart = jsonReader.nextIfObjectStart(); if (!objectStart) { - if (jsonReader.nextIfEmptyString()) { + if (jsonReader.nextIfNullOrEmptyString()) { return null; } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplDate.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplDate.java index 248f0d1d41..60d5414cfa 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplDate.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplDate.java @@ -80,7 +80,7 @@ private Object readDate(JSONReader jsonReader) { } } - if (jsonReader.nextIfEmptyString()) { + if (jsonReader.nextIfNullOrEmptyString()) { return null; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java index 6db397dcf1..5f54aea1b2 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java @@ -221,7 +221,7 @@ public T readObject(JSONReader jsonReader, Type fieldType, Object fieldName, lon boolean objectStart = jsonReader.nextIfObjectStart(); if (!objectStart && !jsonReader.isTypeRedirect()) { - if (jsonReader.nextIfEmptyString()) { + if (jsonReader.nextIfNullOrEmptyString()) { return null; } } diff --git a/core/src/test/java/com/alibaba/fastjson2/JSONBTest5.java b/core/src/test/java/com/alibaba/fastjson2/JSONBTest5.java index a14bb049e9..149ed2ee40 100644 --- a/core/src/test/java/com/alibaba/fastjson2/JSONBTest5.java +++ b/core/src/test/java/com/alibaba/fastjson2/JSONBTest5.java @@ -220,8 +220,8 @@ public void nextIfEmptyString() { JSONReader.ofJSONB( JSONB.toBytes("") ) - .nextIfEmptyString() + .nextIfNullOrEmptyString() ); - assertFalse(JSONReader.ofJSONB(JSONB.toBytes("1")).nextIfEmptyString()); + assertFalse(JSONReader.ofJSONB(JSONB.toBytes("1")).nextIfNullOrEmptyString()); } } diff --git a/core/src/test/java/com/alibaba/fastjson2/JSONReaderStr.java b/core/src/test/java/com/alibaba/fastjson2/JSONReaderStr.java index f81756da23..ba2d51307a 100644 --- a/core/src/test/java/com/alibaba/fastjson2/JSONReaderStr.java +++ b/core/src/test/java/com/alibaba/fastjson2/JSONReaderStr.java @@ -110,8 +110,12 @@ public boolean nextIfMatch(char ch) { } @Override - public boolean nextIfEmptyString() { + public boolean nextIfNullOrEmptyString() { final char first = this.ch; + if (first == 'n' && offset + 2 < end && str.charAt(offset) == 'u') { + this.readNull(); + return true; + } if ((first != '"' && first != '\'') || offset >= end || str.charAt(offset) != first) { return false; } diff --git a/core/src/test/java/com/alibaba/fastjson2/JSONReaderTest1.java b/core/src/test/java/com/alibaba/fastjson2/JSONReaderTest1.java index 34782064fa..bacaa8fc20 100644 --- a/core/src/test/java/com/alibaba/fastjson2/JSONReaderTest1.java +++ b/core/src/test/java/com/alibaba/fastjson2/JSONReaderTest1.java @@ -293,58 +293,58 @@ public void testNextIfSet() { @Test public void testNextIfEmptyString() { for (JSONReader jsonReader : TestUtils.createJSONReaders4("\'\',1")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals('1', jsonReader.ch); assertTrue(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\'\' , 1")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals('1', jsonReader.ch); assertTrue(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders("\'\' , 中")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals('中', jsonReader.ch); assertTrue(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders("\'\' , ®")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals('®', jsonReader.ch); assertTrue(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\"\"")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals(JSONReader.EOI, jsonReader.ch); assertFalse(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\"\",")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals(JSONReader.EOI, jsonReader.ch); assertTrue(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\"\" ,")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals(JSONReader.EOI, jsonReader.ch); assertTrue(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\"\" , ")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals(JSONReader.EOI, jsonReader.ch); assertTrue(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\"\" ")) { - assertTrue(jsonReader.nextIfEmptyString()); + assertTrue(jsonReader.nextIfNullOrEmptyString()); assertEquals(JSONReader.EOI, jsonReader.ch); assertFalse(jsonReader.comma); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\"")) { - assertFalse(jsonReader.nextIfEmptyString()); + assertFalse(jsonReader.nextIfNullOrEmptyString()); } for (JSONReader jsonReader : TestUtils.createJSONReaders4("\"a\"")) { - assertFalse(jsonReader.nextIfEmptyString()); + assertFalse(jsonReader.nextIfNullOrEmptyString()); } } diff --git a/core/src/test/java/com/alibaba/fastjson2/issues/Issue998.java b/core/src/test/java/com/alibaba/fastjson2/issues/Issue998.java new file mode 100644 index 0000000000..04511b849a --- /dev/null +++ b/core/src/test/java/com/alibaba/fastjson2/issues/Issue998.java @@ -0,0 +1,93 @@ +package com.alibaba.fastjson2.issues; + +import com.alibaba.fastjson2.JSON; +import org.junit.jupiter.api.Test; + +import java.io.Serializable; + +import static org.junit.jupiter.api.Assertions.assertNull; + +public class Issue998 { + @Test + public void test() { + String str = "{\"cloudServiceName\":\"xxx\",\"enterpriseCode\":\"xxx\",\"enterpriseName\":\"xxx\",\"serviceCode\":\"IT_MONITOR_MANAGER_SYSTEM\",\"cloudStyle\":\"\"}"; + EnterpriseCloudServiceVO enterpriseCloudServiceVO = JSON.parseObject(str, EnterpriseCloudServiceVO.class); + assertNull(enterpriseCloudServiceVO.cloudStyle); + } + + @Test + public void test1() { + String str = "{\"cloudServiceName\":\"xxx\",\"enterpriseCode\":\"xxx\",\"enterpriseName\":\"xxx\",\"serviceCode\":\"IT_MONITOR_MANAGER_SYSTEM\",\"cloudStyle\":\"\"}"; + EnterpriseCloudServiceVO1 enterpriseCloudServiceVO = JSON.parseObject(str, EnterpriseCloudServiceVO1.class); + assertNull(enterpriseCloudServiceVO.cloudStyle); + } + + public static class EnterpriseCloudServiceVO { + private String enterpriseCode; + private String enterpriseName; + private String serviceCode; + private String cloudServiceName; + private CloudStyle cloudStyle; + + public String getEnterpriseCode() { + return enterpriseCode; + } + + public void setEnterpriseCode(String enterpriseCode) { + this.enterpriseCode = enterpriseCode; + } + + public String getEnterpriseName() { + return enterpriseName; + } + + public void setEnterpriseName(String enterpriseName) { + this.enterpriseName = enterpriseName; + } + + public String getServiceCode() { + return serviceCode; + } + + public void setServiceCode(String serviceCode) { + this.serviceCode = serviceCode; + } + + public String getCloudServiceName() { + return cloudServiceName; + } + + public void setCloudServiceName(String cloudServiceName) { + this.cloudServiceName = cloudServiceName; + } + + public CloudStyle getCloudStyle() { + return cloudStyle; + } + + public void setCloudStyle(CloudStyle cloudStyle) { + this.cloudStyle = cloudStyle; + } + } + + private static class EnterpriseCloudServiceVO1 { + public String enterpriseCode; + public String enterpriseName; + public String serviceCode; + public String cloudServiceName; + public CloudStyle cloudStyle; + } + + public static class CloudStyle + implements Serializable { + private Integer modelId; + + public Integer getModelId() { + return modelId; + } + + public void setModelId(Integer modelId) { + this.modelId = modelId; + } + } +}