diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONType.java b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java index 84aae7827..ba9347292 100755 --- a/src/main/java/com/alibaba/fastjson/annotation/JSONType.java +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java @@ -23,4 +23,6 @@ public @interface JSONType { SerializerFeature[] serialzeFeatures() default {}; boolean alphabetic() default true; + + Class mappingTo() default Void.class; } diff --git a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java index d72550b6d..2bf31150b 100755 --- a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java +++ b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java @@ -57,6 +57,7 @@ import java.util.regex.Pattern; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.asm.ASMException; import com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory; import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; @@ -309,6 +310,16 @@ public class ParserConfig { if (derializer != null) { return derializer; } + + { + JSONType annotation = clazz.getAnnotation(JSONType.class); + if (annotation != null) { + Class mappingTo = annotation.mappingTo(); + if (mappingTo != Void.class) { + return getDeserializer(mappingTo, mappingTo); + } + } + } if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) { derializer = derializers.get(clazz); diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest.java index 93ed7e7e8..e52f77ad8 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest.java @@ -5,14 +5,13 @@ import junit.framework.TestCase; import org.junit.Assert; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; public class AbstractSerializeTest extends TestCase { protected void setUp() throws Exception { - ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); - ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); } protected void tearDown() throws Exception { @@ -22,9 +21,6 @@ public class AbstractSerializeTest extends TestCase { public void test_mapping_0() throws Exception { String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\"}"; - ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); - ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); - B b = (B) JSON.parse(text); Assert.assertNotNull(b); } @@ -32,9 +28,6 @@ public class AbstractSerializeTest extends TestCase { public void test_mapping_1() throws Exception { String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\",\"id\":123}"; - ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); - ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); - B b = (B) JSON.parse(text); Assert.assertNotNull(b); Assert.assertEquals(123, b.getId()); @@ -55,9 +48,6 @@ public class AbstractSerializeTest extends TestCase { public void test_mapping_group() throws Exception { String text = "{\"a\":{\"id\":234,\"name\":\"abc\"}}"; - ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); - ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); - G g = JSON.parseObject(text, G.class); Assert.assertTrue(g.getA() instanceof B); } @@ -76,6 +66,7 @@ public class AbstractSerializeTest extends TestCase { } + @JSONType(mappingTo = B.class) public static abstract class A { private int id; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest2.java new file mode 100644 index 000000000..a923caad3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest2.java @@ -0,0 +1,104 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class AbstractSerializeTest2 extends TestCase { + + protected void setUp() throws Exception { + ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); + ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); + } + + protected void tearDown() throws Exception { + ParserConfig.getGlobalInstance().putDeserializer(A.class, null); + } + + public void test_mapping_0() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\"}"; + + ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); + ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + } + + public void test_mapping_1() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\",\"id\":123}"; + + ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); + ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + Assert.assertEquals(123, b.getId()); + } + + public void test_mapping_2() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\",\"id\":234,\"name\":\"abc\"}"; + + ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); + ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + Assert.assertEquals(234, b.getId()); + Assert.assertEquals("abc", b.getName()); + } + + public void test_mapping_group() throws Exception { + String text = "{\"a\":{\"id\":234,\"name\":\"abc\"}}"; + + ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); + ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); + + G g = JSON.parseObject(text, G.class); + Assert.assertTrue(g.getA() instanceof B); + } + + public static class G { + + private A a; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } + + public static abstract class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } + + public static class B extends A { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +}