mirror of
https://github.com/alibaba/fastjson.git
synced 2026-10-23 09:58:34 +08:00
新增SerializerFeature.WriteEnumUsingName用于在序列化时输出枚举的name()值。
Release Notes(1.1.42) https://github.com/alibaba/fastjson/wiki/Release-Notes(1.1.42) “修复序列化时SerializerFeature.WriteEnumUsingToString不生效的bug“,这种做法会引起问题。如果重写了枚举的toString方法,会导致反序列化失败。而且,此fix (https://github.com/alibaba/fastjson/commit/6a2b502455b54367cc2554eb5e00d27056c07f13)只修改了部分代码,还有几个地方在启用WriteEnumUsingToString特性时,仍然使用name()。 此修改序列化枚举时默认用枚举的name()值,和以前的版本保持一致,并且修改了所有使用WriteEnumUsingToString特性的代码,让他真正生效。
This commit is contained in:
@@ -88,7 +88,7 @@ public abstract class JSON implements JSONStreamAware, JSONAware {
|
||||
int features = 0;
|
||||
features |= SerializerFeature.QuoteFieldNames.getMask();
|
||||
features |= SerializerFeature.SkipTransientField.getMask();
|
||||
features |= SerializerFeature.WriteEnumUsingToString.getMask();
|
||||
features |= SerializerFeature.WriteEnumUsingName.getMask();
|
||||
features |= SerializerFeature.SortField.getMask();
|
||||
// features |=
|
||||
// com.alibaba.fastjson.serializer.SerializerFeature.WriteSlashAsSpecial.getMask();
|
||||
|
||||
@@ -32,11 +32,12 @@ public class EnumSerializer implements ObjectSerializer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (serializer.isEnabled(SerializerFeature.WriteEnumUsingToString)) {
|
||||
Enum<?> e = (Enum<?>) object;
|
||||
Enum<?> e = (Enum<?>) object;
|
||||
if(serializer.isEnabled(SerializerFeature.WriteEnumUsingName)){
|
||||
serializer.write(e.name());
|
||||
} else if (serializer.isEnabled(SerializerFeature.WriteEnumUsingToString)) {
|
||||
serializer.write(e.toString());
|
||||
} else {
|
||||
Enum<?> e = (Enum<?>) object;
|
||||
out.writeInt(e.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package com.alibaba.fastjson.serializer;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.alibaba.fastjson.util.FieldInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author wenshao[szujobs@hotmail.com]
|
||||
*/
|
||||
@@ -31,6 +31,7 @@ public class ObjectFieldSerializer extends FieldSerializer {
|
||||
boolean writeNullBooleanAsFalse = false;
|
||||
boolean writeNullListAsEmpty = false;
|
||||
boolean writeEnumUsingToString = false;
|
||||
boolean writeEnumUsingName = false;
|
||||
|
||||
private RuntimeSerializerInfo runtimeInfo;
|
||||
|
||||
@@ -57,6 +58,8 @@ public class ObjectFieldSerializer extends FieldSerializer {
|
||||
writeNullListAsEmpty = true;
|
||||
} else if (feature == SerializerFeature.WriteEnumUsingToString) {
|
||||
writeEnumUsingToString = true;
|
||||
}else if(feature == SerializerFeature.WriteEnumUsingName){
|
||||
writeEnumUsingName = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,9 +113,15 @@ public class ObjectFieldSerializer extends FieldSerializer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (writeEnumUsingToString == true && runtimeInfo.runtimeFieldClass.isEnum()) {
|
||||
serializer.getWriter().writeString(((Enum<?>) propertyValue).name());
|
||||
return;
|
||||
if(runtimeInfo.runtimeFieldClass.isEnum()){
|
||||
if(writeEnumUsingName){
|
||||
serializer.getWriter().writeString(((Enum<?>) propertyValue).name());
|
||||
return;
|
||||
}
|
||||
if(writeEnumUsingToString){
|
||||
serializer.getWriter().writeString(((Enum<?>) propertyValue).toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> valueClass = propertyValue.getClass();
|
||||
|
||||
@@ -115,6 +115,12 @@ public final class SerializeWriter extends Writer {
|
||||
public void config(SerializerFeature feature, boolean state) {
|
||||
if (state) {
|
||||
features |= feature.getMask();
|
||||
//由于枚举序列化特性WriteEnumUsingToString和WriteEnumUsingName不能共存,需要检查
|
||||
if(feature == SerializerFeature.WriteEnumUsingToString){
|
||||
features &= ~SerializerFeature.WriteEnumUsingName.getMask();
|
||||
}else if(feature == SerializerFeature.WriteEnumUsingName){
|
||||
features &= ~SerializerFeature.WriteEnumUsingToString.getMask();
|
||||
}
|
||||
} else {
|
||||
features &= ~feature.getMask();
|
||||
}
|
||||
@@ -499,25 +505,34 @@ public final class SerializeWriter extends Writer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEnabled(SerializerFeature.WriteEnumUsingToString)) {
|
||||
if (isEnabled(SerializerFeature.UseSingleQuotes)) {
|
||||
write('\'');
|
||||
write(value.name());
|
||||
write('\'');
|
||||
write(c);
|
||||
if (isEnabled(SerializerFeature.WriteEnumUsingName)) {
|
||||
writeEnumValue(value.name(),c);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
write('\"');
|
||||
write(value.name());
|
||||
write('\"');
|
||||
write(c);
|
||||
}
|
||||
if (isEnabled(SerializerFeature.WriteEnumUsingToString)) {
|
||||
writeEnumValue(value.toString(),c);
|
||||
return;
|
||||
}
|
||||
|
||||
writeIntAndChar(value.ordinal(), c);
|
||||
}
|
||||
|
||||
private void writeEnumValue(String value,char c){
|
||||
if (isEnabled(SerializerFeature.UseSingleQuotes)) {
|
||||
write('\'');
|
||||
write(value);
|
||||
write('\'');
|
||||
write(c);
|
||||
|
||||
} else {
|
||||
write('\"');
|
||||
write(value);
|
||||
write('\"');
|
||||
write(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeIntAndChar(int i, char c) {
|
||||
if (i == Integer.MIN_VALUE) {
|
||||
write("-2147483648");
|
||||
@@ -1423,20 +1438,23 @@ public final class SerializeWriter extends Writer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEnabled(SerializerFeature.WriteEnumUsingToString)) {
|
||||
if (isEnabled(SerializerFeature.UseSingleQuotes)) {
|
||||
writeFieldValue(seperator, name, value.name());
|
||||
} else {
|
||||
writeFieldValueStringWithDoubleQuote(seperator, name, value.name(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
// writeStringWithDoubleQuote
|
||||
if (isEnabled(SerializerFeature.WriteEnumUsingName)) {
|
||||
writeEnumFieldValue(seperator,name,value.name());
|
||||
}else if(isEnabled(SerializerFeature.WriteEnumUsingToString)){
|
||||
writeEnumFieldValue(seperator,name,value.toString());
|
||||
} else {
|
||||
writeFieldValue(seperator, name, value.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeEnumFieldValue(char seperator,String name,String value){
|
||||
if (isEnabled(SerializerFeature.UseSingleQuotes)) {
|
||||
writeFieldValue(seperator, name, value);
|
||||
} else {
|
||||
writeFieldValueStringWithDoubleQuote(seperator, name, value, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFieldValue(char seperator, String name, BigDecimal value) {
|
||||
write(seperator);
|
||||
writeFieldName(name);
|
||||
|
||||
@@ -29,9 +29,13 @@ public enum SerializerFeature {
|
||||
*/
|
||||
WriteMapNullValue,
|
||||
/**
|
||||
*
|
||||
* 用枚举toString()值输出
|
||||
*/
|
||||
WriteEnumUsingToString,
|
||||
/**
|
||||
* 用枚举name()输出
|
||||
*/
|
||||
WriteEnumUsingName,
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* www.yiji.com Inc.
|
||||
* Copyright (c) 2014 All Rights Reserved
|
||||
*/
|
||||
|
||||
/*
|
||||
* 修订记录:
|
||||
* qzhanbo@yiji.com 2015-03-01 00:55 创建
|
||||
*
|
||||
*/
|
||||
package com.alibaba.json.bvt.serializer;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializeWriter;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author bohr.qiu@gmail.com
|
||||
*/
|
||||
public class EnumTest3 {
|
||||
@Test
|
||||
public void testDefault() throws Exception {
|
||||
String json = JSON.toJSONString(Sex.M);
|
||||
Assert.assertEquals(json, "\"M\"");
|
||||
|
||||
Pojo pojo = new Pojo();
|
||||
pojo.setSex(Sex.M);
|
||||
json = JSON.toJSONString(pojo);
|
||||
Assert.assertEquals(json, "{\"sex\":\"M\"}");
|
||||
|
||||
try {
|
||||
JSON.parseObject(json, Pojo.class);
|
||||
Assert.assertTrue(true);
|
||||
} catch (Exception e) {
|
||||
Assert.fail("枚举默认序列化name值,可以反序列化成功");
|
||||
}
|
||||
|
||||
Map<String, Pojo> map = new HashMap<String, Pojo>();
|
||||
map.put("a", pojo);
|
||||
json = JSON.toJSONString(map);
|
||||
Assert.assertEquals(json, "{\"a\":{\"sex\":\"M\"}}");
|
||||
|
||||
Map<Sex, Pojo> enumMap = new EnumMap<Sex, Pojo>(Sex.class);
|
||||
enumMap.put(Sex.M, pojo);
|
||||
json = JSON.toJSONString(enumMap);
|
||||
Assert.assertEquals(json, "{\"M\":{\"sex\":\"M\"}}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefault1() throws Exception {
|
||||
JSON.DUMP_CLASS = "/Users/bohr/Downloads/tmp";
|
||||
String json = JSON.toJSONString(Sex.M, SerializerFeature.WriteEnumUsingToString);
|
||||
Assert.assertEquals(json, "\"男\"");
|
||||
|
||||
Pojo pojo = new Pojo();
|
||||
pojo.setSex(Sex.M);
|
||||
json = JSON.toJSONString(pojo, SerializerFeature.WriteEnumUsingToString);
|
||||
Assert.assertEquals(json, "{\"sex\":\"男\"}");
|
||||
|
||||
try {
|
||||
JSON.parseObject(json, Pojo.class);
|
||||
Assert.fail("toString的结果不能转换成枚举");
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
Map<String, Pojo> map = new HashMap<String, Pojo>();
|
||||
map.put("a", pojo);
|
||||
json = JSON.toJSONString(map, SerializerFeature.WriteEnumUsingToString);
|
||||
Assert.assertEquals(json, "{\"a\":{\"sex\":\"男\"}}");
|
||||
|
||||
Map<Sex, Pojo> enumMap = new EnumMap<Sex, Pojo>(Sex.class);
|
||||
enumMap.put(Sex.M, pojo);
|
||||
json = JSON.toJSONString(enumMap, SerializerFeature.WriteEnumUsingToString);
|
||||
Assert.assertEquals(json, "{\"男\":{\"sex\":\"男\"}}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() throws Exception {
|
||||
Assert.assertEquals("\"男\"", JSON.toJSONString(Sex.M, SerializerFeature.WriteEnumUsingToString));
|
||||
Assert.assertEquals("\"女\"", JSON.toJSONString(Sex.W, SerializerFeature.WriteEnumUsingToString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriterSerializerFeature() throws Exception {
|
||||
SerializeWriter writer=new SerializeWriter();
|
||||
writer.config(SerializerFeature.WriteEnumUsingToString,true);
|
||||
Assert.assertTrue(writer.isEnabled(SerializerFeature.WriteEnumUsingToString));
|
||||
writer.config(SerializerFeature.WriteEnumUsingName,true);
|
||||
Assert.assertTrue(writer.isEnabled(SerializerFeature.WriteEnumUsingName));
|
||||
Assert.assertFalse(writer.isEnabled(SerializerFeature.WriteEnumUsingToString));
|
||||
writer.config(SerializerFeature.WriteEnumUsingToString,true);
|
||||
Assert.assertTrue(writer.isEnabled(SerializerFeature.WriteEnumUsingToString));
|
||||
Assert.assertFalse(writer.isEnabled(SerializerFeature.WriteEnumUsingName));
|
||||
}
|
||||
|
||||
public static enum Sex {
|
||||
M("男"),
|
||||
W("女");
|
||||
private String msg;
|
||||
|
||||
Sex(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Pojo {
|
||||
private Sex sex;
|
||||
|
||||
public Sex getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(Sex sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user