Skip to content

Commit

Permalink
improved JSONField WriteClassName support.
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Sep 16, 2017
1 parent 14b5888 commit f47d324
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 22 deletions.
11 changes: 9 additions & 2 deletions src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java
Expand Up @@ -292,10 +292,17 @@ public final Object parseObject(final Map object, Object fieldName) {

lexer.resetStringPosition();

if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
if (key == JSON.DEFAULT_TYPE_KEY
&& !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
String typeName = lexer.scanSymbol(symbolTable, '"');

if (lexer.isEnabled(Feature.IgnoreAutoType)) {
continue;
}

Class<?> clazz = null;
if (object != null && object.getClass().getName().equals(typeName)) {
if (object != null
&& object.getClass().getName().equals(typeName)) {
clazz = object.getClass();
} else {
clazz = config.checkAutoType(typeName, null);
Expand Down
Expand Up @@ -45,7 +45,9 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty
}

Type elementType = null;
if (out.isEnabled(SerializerFeature.WriteClassName)) {
if (out.isEnabled(SerializerFeature.WriteClassName)
|| SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName))
{
elementType = TypeUtils.getCollectionItemType(fieldType);
}

Expand Down
Expand Up @@ -19,6 +19,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.*;

import com.alibaba.fastjson.JSONException;
Expand Down Expand Up @@ -170,7 +171,15 @@ protected void write(JSONSerializer serializer, //
||(features & SerializerFeature.WriteClassName.mask) != 0
|| serializer.isWriteClassName(fieldType, object)) {
Class<?> objClass = object.getClass();
if (objClass != fieldType) {

final Type type;
if (objClass != fieldType && fieldType instanceof WildcardType) {
type = TypeUtils.getClass(fieldType);
} else {
type = fieldType;
}

if (objClass != type) {
writeClassName(serializer, beanInfo.typeKey, object);
commaFlag = true;
}
Expand Down
Expand Up @@ -33,7 +33,8 @@ public final class ListSerializer implements ObjectSerializer {
public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {

boolean writeClassName = serializer.out.isEnabled(SerializerFeature.WriteClassName);
boolean writeClassName = serializer.out.isEnabled(SerializerFeature.WriteClassName)
|| SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName);

SerializeWriter out = serializer.out;

Expand Down
12 changes: 11 additions & 1 deletion src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java
Expand Up @@ -16,6 +16,7 @@
package com.alibaba.fastjson.serializer;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

Expand Down Expand Up @@ -250,8 +251,17 @@ public void write(JSONSerializer serializer

if (SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName)
&& preWriter instanceof JavaBeanSerializer) {
Type valueType = null;
if (fieldType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) fieldType;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
if (actualTypeArguments.length == 2) {
valueType = actualTypeArguments[1];
}
}

JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer) preWriter;
javaBeanSerializer.writeNoneASM(serializer, value, entryKey, null, features);
javaBeanSerializer.writeNoneASM(serializer, value, entryKey, valueType, features);
} else {
preWriter.write(serializer, value, entryKey, null, features);
}
Expand Down
Expand Up @@ -16,10 +16,11 @@ public void test_list() throws Exception {
Model model = new Model();
List tables = new ArrayList();
tables.add(new ExtTable(1001));
tables.add(new Table());
model.setTables(tables);

String json = JSON.toJSONString(model);
assertEquals("{\"tables\":[{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_List3$ExtTable\",\"id\":1001}]}", json);
assertEquals("{\"tables\":[{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_List3$ExtTable\",\"id\":1001},{}]}", json);

Model model2 = JSON.parseObject(json, Model.class);
assertEquals(ExtTable.class, model2.getTables().iterator().next().getClass());
Expand Down
@@ -1,28 +1,31 @@
package com.alibaba.json.bvt.writeClassName;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import junit.framework.TestCase;
import org.junit.Assert;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.*;

public class WriteClassNameTest_Map extends TestCase {

public void test_list() throws Exception {
Model model = new Model();
Map tables = new HashMap();
Map tables = new LinkedHashMap();
tables.put("1001", new ExtTable(1001));
tables.put("1002", new Table());
model.setTables(tables);

String json = JSON.toJSONString(model);
assertEquals("{\"tables\":{\"1001\":{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Map$ExtTable\",\"id\":1001}}}", json);
assertEquals("{\"tables\":{\"1001\":{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Map$ExtTable\",\"id\":1001},\"1002\":{}}}", json);

JSONObject jsonObject = JSON.parseObject(json, Feature.IgnoreAutoType);
assertEquals("{\"tables\":{\"1002\":{},\"1001\":{\"id\":1001}}}", jsonObject.toJSONString());

Model model2 = JSON.parseObject(json, Model.class);
assertEquals(ExtTable.class, model2.getTables().get("1001").getClass());
Expand Down
@@ -1,39 +1,42 @@
package com.alibaba.json.bvt.writeClassName;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import junit.framework.TestCase;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;

public class WriteClassNameTest_Set5 extends TestCase {

public void test_list() throws Exception {
Model model = new Model();
Set tables = new HashSet();
LinkedHashSet tables = new LinkedHashSet();
tables.add(new ExtTable(1001));
tables.add(new Table());
model.setTables(tables);

String json = JSON.toJSONString(model);
assertEquals("{\"tables\":[{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set5$ExtTable\",\"id\":1001}]}", json);
assertEquals("{\"tables\":[{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set5$ExtTable\",\"id\":1001},{}]}", json);

Model model2 = JSON.parseObject(json, Model.class);
assertEquals(ExtTable.class, model2.getTables().iterator().next().getClass());

JSONObject jsonObject = JSON.parseObject(json, Feature.IgnoreAutoType);
assertEquals("{\"tables\":[{\"id\":1001},{}]}", jsonObject.toJSONString());
}

public static class Model {
@JSONField(serialzeFeatures = SerializerFeature.WriteClassName)
private Set<? extends Table> tables;
private LinkedHashSet<? extends Table> tables;

public Set<? extends Table> getTables() {
public LinkedHashSet<? extends Table> getTables() {
return tables;
}

public void setTables(Set<? extends Table> tables) {
public void setTables(LinkedHashSet<? extends Table> tables) {
this.tables = tables;
}
}
Expand Down

0 comments on commit f47d324

Please sign in to comment.