diff --git a/src/main/java/com/alibaba/fastjson/JSON.java b/src/main/java/com/alibaba/fastjson/JSON.java index 510184f41..2ba087e4c 100755 --- a/src/main/java/com/alibaba/fastjson/JSON.java +++ b/src/main/java/com/alibaba/fastjson/JSON.java @@ -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(); diff --git a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java index 987767a76..0cf249729 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java @@ -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()); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java index 1d0708b82..184cb7c8a 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java @@ -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(); diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java index f6ed80a9b..7955660e0 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java @@ -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); diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java index 3c2b045a7..dd5d67969 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java @@ -29,9 +29,13 @@ public enum SerializerFeature { */ WriteMapNullValue, /** - * + * 用枚举toString()值输出 */ WriteEnumUsingToString, + /** + * 用枚举name()输出 + */ + WriteEnumUsingName, /** * */ diff --git a/src/test/java/com/alibaba/json/bvt/serializer/EnumTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest3.java new file mode 100644 index 000000000..62c7152bd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest3.java @@ -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 map = new HashMap(); + map.put("a", pojo); + json = JSON.toJSONString(map); + Assert.assertEquals(json, "{\"a\":{\"sex\":\"M\"}}"); + + Map enumMap = new EnumMap(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 map = new HashMap(); + map.put("a", pojo); + json = JSON.toJSONString(map, SerializerFeature.WriteEnumUsingToString); + Assert.assertEquals(json, "{\"a\":{\"sex\":\"男\"}}"); + + Map enumMap = new EnumMap(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; + } + } +}