diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java index 5addc77c4..dfa8ba1fb 100644 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java @@ -26,6 +26,40 @@ public class DefaultObjectDeserializer implements ObjectDeserializer { public DefaultObjectDeserializer(){ } + public void parseMap(DefaultJSONParser parser, Map map, Type keyType, Type valueType) { + JSONScanner lexer = (JSONScanner) parser.getLexer(); + + if (lexer.token() != JSONToken.LBRACE) { + throw new JSONException("syntax error, expect {, actual " + lexer.token()); + } + + ObjectDeserializer keyDeserializer = parser.getConfig().getDeserializer(keyType); + ObjectDeserializer valueDeserializer = parser.getConfig().getDeserializer(valueType); + lexer.nextToken(keyDeserializer.getFastMatchToken()); + + for (;;) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + + Object key = keyDeserializer.deserialze(parser, keyType, null); + + if (lexer.token() != JSONToken.COLON) { + throw new JSONException("syntax error, expect :, actual " + lexer.token()); + } + + lexer.nextToken(valueDeserializer.getFastMatchToken()); + Object value = valueDeserializer.deserialze(parser, valueType, key); + + map.put(key, value); + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(keyDeserializer.getFastMatchToken()); + } + } + } + public void parseMap(DefaultJSONParser parser, Map map, Type valueType) { JSONScanner lexer = (JSONScanner) parser.getLexer(); @@ -165,7 +199,8 @@ public class DefaultObjectDeserializer implements ObjectDeserializer { lexer.nextTokenWithColon(JSONToken.LBRACE); args[0] = CollectionDeserializer.instance.deserialze(parser, fieldType, null); } else { - ObjectDeserializer fieldValueDeserializer = parser.getConfig().getDeserializer(fieldClass, fieldType); + ObjectDeserializer fieldValueDeserializer = parser.getConfig().getDeserializer(fieldClass, + fieldType); lexer.nextTokenWithColon(fieldValueDeserializer.getFastMatchToken()); args[0] = fieldValueDeserializer.deserialze(parser, fieldType, null); @@ -238,9 +273,14 @@ public class DefaultObjectDeserializer implements ObjectDeserializer { } } + Type keyType = type.getActualTypeArguments()[0]; Type valueType = type.getActualTypeArguments()[1]; - parseMap(parser, map, valueType); + if (keyType == String.class) { + parseMap(parser, map, valueType); + } else { + parseMap(parser, map, keyType, valueType); + } return (T) map; } @@ -258,13 +298,13 @@ public class DefaultObjectDeserializer implements ObjectDeserializer { @SuppressWarnings({ "rawtypes", "unchecked" }) public T deserialze(DefaultJSONParser parser, Class clazz) { Object value = null; - if (clazz.isAssignableFrom(HashMap.class)) { - value = new HashMap(); - } else if (clazz.isAssignableFrom(TreeMap.class)) { - value = new TreeMap(); - } else if (clazz.isAssignableFrom(ConcurrentHashMap.class)) { - value = new ConcurrentHashMap(); - } + if (clazz.isAssignableFrom(HashMap.class)) { + value = new HashMap(); + } else if (clazz.isAssignableFrom(TreeMap.class)) { + value = new TreeMap(); + } else if (clazz.isAssignableFrom(ConcurrentHashMap.class)) { + value = new ConcurrentHashMap(); + } if (clazz == Class.class) { Object classValue = parser.parse(); diff --git a/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java index 1686c0139..a1fc14200 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java @@ -52,48 +52,58 @@ public class MapSerializer implements ObjectSerializer { Object value = entry.getValue(); Object entryKey = entry.getKey(); - String key = entryKey == null ? "null" : entryKey.toString(); - List propertyFilters = serializer.getPropertyFiltersDirect(); - if (propertyFilters != null) { - boolean apply = true; - for (PropertyFilter propertyFilter : propertyFilters) { - if (!propertyFilter.apply(object, key, value)) { - apply = false; - break; + if (entryKey == null || entryKey instanceof String) { + String key = (String) entryKey; + List propertyFilters = serializer.getPropertyFiltersDirect(); + if (propertyFilters != null) { + boolean apply = true; + for (PropertyFilter propertyFilter : propertyFilters) { + if (!propertyFilter.apply(object, key, value)) { + apply = false; + break; + } + } + + if (!apply) { + continue; } } - if (!apply) { - continue; + List nameFilters = serializer.getNameFiltersDirect(); + if (nameFilters != null) { + for (NameFilter nameFilter : nameFilters) { + key = nameFilter.process(object, key, value); + } } - } - List nameFilters = serializer.getNameFiltersDirect(); - if (nameFilters != null) { - for (NameFilter nameFilter : nameFilters) { - key = nameFilter.process(object, key, value); + List valueFilters = serializer.getValueFiltersDirect(); + if (valueFilters != null) { + for (ValueFilter valueFilter : valueFilters) { + value = valueFilter.process(object, key, value); + } } - } - - List valueFilters = serializer.getValueFiltersDirect(); - if (valueFilters != null) { - for (ValueFilter valueFilter : valueFilters) { - value = valueFilter.process(object, key, value); + + if (value == null) { + if (!serializer.isEnabled(SerializerFeature.WriteMapNullValue)) { + continue; + } } - } - - if (value == null) { - if (!serializer.isEnabled(SerializerFeature.WriteMapNullValue)) { - continue; + + if (!first) { + out.write(','); } + + out.writeFieldName(key); + } else { + if (!first) { + out.write(','); + } + + serializer.write(entryKey); + out.write(':'); } - - if (!first) { - out.write(','); - } - - out.writeFieldName(key); + first = false; if (value == null) { diff --git a/src/test/java/com/alibaba/json/test/bvt/SpecialKeyTest.java b/src/test/java/com/alibaba/json/test/bvt/SpecialKeyTest.java new file mode 100644 index 000000000..1c7eaa479 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/bvt/SpecialKeyTest.java @@ -0,0 +1,23 @@ +package com.alibaba.json.test.bvt; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class SpecialKeyTest extends TestCase { + + public void test_0() throws Exception { + Map map = new HashMap(); + map.put(1, "a"); + map.put(2, "b"); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/WriteClassNameTest.java b/src/test/java/com/alibaba/json/test/bvt/WriteClassNameTest.java index 391cf8339..933884d72 100644 --- a/src/test/java/com/alibaba/json/test/bvt/WriteClassNameTest.java +++ b/src/test/java/com/alibaba/json/test/bvt/WriteClassNameTest.java @@ -8,45 +8,45 @@ import com.alibaba.fastjson.serializer.SerializerFeature; public class WriteClassNameTest extends TestCase { -public void test_0() throws Exception { - Entity entity = new Entity(3, "jobs"); - String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); - System.out.println(text); - - Entity entity2 = (Entity) JSON.parseObject(text, Object.class); - - Assert.assertEquals(entity.getId(), entity2.getId()); - Assert.assertEquals(entity.getName(), entity2.getName()); -} - -public static class Entity { - - private int id; - private String name; - - public Entity(){ - } - - public Entity(int id, String name){ - this.id = id; - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} + public void test_0() throws Exception { + Entity entity = new Entity(3, "jobs"); + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + + Entity entity2 = (Entity) JSON.parseObject(text, Object.class); + + Assert.assertEquals(entity.getId(), entity2.getId()); + Assert.assertEquals(entity.getName(), entity2.getName()); + } + + public static class Entity { + + private int id; + private String name; + + public Entity(){ + } + + public Entity(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } }