writeEnum default use name, for issue #1355

This commit is contained in:
shaojin.wensj 2023-04-13 23:00:05 +08:00
parent 075249de2b
commit 357a128b30
5 changed files with 79 additions and 32 deletions

View File

@ -1867,7 +1867,8 @@ public abstract class JSONWriter
/**
* @since 2.0.20
*/
BrowserSecure(1L << 35);
BrowserSecure(1L << 35),
WriteEnumUsingOrdinal(1L << 36),;
public final long mask;

View File

@ -196,7 +196,8 @@ class FieldWriterEnum
return;
}
final boolean usingOrdinal = (features & (JSONWriter.Feature.WriteEnumUsingToString.mask | JSONWriter.Feature.WriteEnumsUsingName.mask)) == 0;
final boolean usingOrdinal = (features & JSONWriter.Feature.WriteEnumUsingOrdinal.mask) != 0;
final boolean usingName = (features & JSONWriter.Feature.WriteEnumsUsingName.mask) != 0;
final boolean utf8 = jsonWriter.utf8;
final boolean utf16 = utf8 ? false : jsonWriter.utf16;
final int ordinal = e.ordinal();
@ -233,37 +234,39 @@ class FieldWriterEnum
return;
}
if (utf8) {
byte[] bytes = valueNameCacheUTF8[ordinal];
if (usingName) {
if (utf8) {
byte[] bytes = valueNameCacheUTF8[ordinal];
if (bytes == null) {
byte[] nameUft8Bytes = enumConstants[ordinal].name().getBytes(StandardCharsets.UTF_8);
bytes = Arrays.copyOf(nameWithColonUTF8, nameWithColonUTF8.length + nameUft8Bytes.length + 2);
bytes[nameWithColonUTF8.length] = '"';
int index = nameWithColonUTF8.length + 1;
for (byte b : nameUft8Bytes) {
bytes[index++] = b;
if (bytes == null) {
byte[] nameUft8Bytes = enumConstants[ordinal].name().getBytes(StandardCharsets.UTF_8);
bytes = Arrays.copyOf(nameWithColonUTF8, nameWithColonUTF8.length + nameUft8Bytes.length + 2);
bytes[nameWithColonUTF8.length] = '"';
int index = nameWithColonUTF8.length + 1;
for (byte b : nameUft8Bytes) {
bytes[index++] = b;
}
bytes[bytes.length - 1] = '"';
valueNameCacheUTF8[ordinal] = bytes;
}
bytes[bytes.length - 1] = '"';
valueNameCacheUTF8[ordinal] = bytes;
jsonWriter.writeNameRaw(bytes);
return;
}
jsonWriter.writeNameRaw(bytes);
return;
}
if (utf16) {
char[] chars = valueNameCacheUTF16[ordinal];
if (utf16) {
char[] chars = valueNameCacheUTF16[ordinal];
if (chars == null) {
String name = enumConstants[ordinal].name();
chars = Arrays.copyOf(nameWithColonUTF16, nameWithColonUTF16.length + name.length() + 2);
chars[nameWithColonUTF16.length] = '"';
name.getChars(0, name.length(), chars, nameWithColonUTF16.length + 1);
chars[chars.length - 1] = '"';
valueNameCacheUTF16[ordinal] = chars;
if (chars == null) {
String name = enumConstants[ordinal].name();
chars = Arrays.copyOf(nameWithColonUTF16, nameWithColonUTF16.length + name.length() + 2);
chars[nameWithColonUTF16.length] = '"';
name.getChars(0, name.length(), chars, nameWithColonUTF16.length + 1);
chars[chars.length - 1] = '"';
valueNameCacheUTF16[ordinal] = chars;
}
jsonWriter.writeNameRaw(chars);
return;
}
jsonWriter.writeNameRaw(chars);
return;
}
if (jsonWriter.jsonb) {
@ -272,7 +275,7 @@ class FieldWriterEnum
}
writeFieldName(jsonWriter);
jsonWriter.writeString(e.name());
jsonWriter.writeString(e.toString());
}
@Override

View File

@ -0,0 +1,31 @@
package com.alibaba.fastjson2.issues_1000;
import com.alibaba.fastjson2.JSON;
import lombok.Builder;
import lombok.Data;
import org.junit.jupiter.api.Test;
public class Issue1355 {
@Test
public void test() {
System.out.println(
JSON.toJSONString(TestDTO.builder().testEnum(TestEnum.E1).build())
);
System.out.println(
com.alibaba.fastjson.JSON.toJSONString(TestDTO.builder().testEnum(TestEnum.E1).build())
);
System.out.println(
JSON.toJSONString(TestEnum.E1)
);
}
@Data
@Builder
public static class TestDTO {
private TestEnum testEnum;
}
public enum TestEnum {
E1, E2;
}
}

View File

@ -69,7 +69,7 @@ public class Enum_0 {
VO vo = new VO();
vo.setValue(Type.T0);
objectWriter.write(jsonWriter, vo);
assertEquals("{\"value\":0}",
assertEquals("{\"value\":\"T0\"}",
jsonWriter.toString());
}
{
@ -77,7 +77,7 @@ public class Enum_0 {
VO vo = new VO();
vo.setValue(Type.T0);
objectWriter.write(jsonWriter, vo);
assertEquals("{\"value\":0}",
assertEquals("{\"value\":\"T0\"}",
jsonWriter.toString());
}
@ -404,6 +404,18 @@ public class Enum_0 {
vo.setValue(id);
byte[] utf8Bytes = JSON.toJSONBytes(vo);
VO v1 = JSON.parseObject(utf8Bytes, 0, utf8Bytes.length, StandardCharsets.UTF_8, VO.class);
assertEquals(vo.getValue(), v1.getValue());
}
}
@Test
public void test_ordinal() {
for (Type id : types) {
VO vo = new VO();
vo.setValue(id);
byte[] utf8Bytes = JSON.toJSONBytes(vo, JSONWriter.Feature.WriteEnumUsingOrdinal);
VO v1 = JSON.parseObject(utf8Bytes, 0, utf8Bytes.length, StandardCharsets.US_ASCII, VO.class);
assertEquals(vo.getValue(), v1.getValue());
}

View File

@ -17,8 +17,8 @@ public class Enum_1 {
Bean bean = new Bean();
bean.unit = TimeUnit.DAYS;
assertEquals("{\"unit\":\"" + bean.unit.name() + "\"}", JSON.toJSONString(bean, JSONWriter.Feature.WriteEnumsUsingName));
assertEquals("{\"unit\":" + bean.unit.ordinal() + "}", JSON.toJSONString(bean));
assertEquals("{\"unit\":\"" + bean.unit.name() + "\"}", JSON.toJSONString(bean, JSONWriter.Feature.WriteEnumUsingToString));
assertEquals("{\"unit\":\"" + bean.unit.name() + "\"}", JSON.toJSONString(bean));
assertEquals(TimeUnit.DAYS, JSON.parseObject("{\"unit\":6}", Bean.class).unit);
assertEquals(TimeUnit.DAYS, JSON.parseObject("{\"unit\":6}").to(Bean.class).unit);