diff --git a/pom.xml b/pom.xml
index 6097038c1..4fa22e7c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.alibaba
fastjson
- 1.1.19
+ 1.1.20-SNAPSHOT
jar
fastjson
@@ -186,6 +186,13 @@
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.0.1
+ test
+
+
org.codehaus.jackson
jackson-core-lgpl
diff --git a/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java b/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java
index 5180df3ea..646dbe1f0 100644
--- a/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java
+++ b/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java
@@ -9,7 +9,6 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -114,7 +113,7 @@ public class ASMSerializerFactory implements Opcodes {
throw new JSONException("unsupportd class " + clazz.getName());
}
- List getters = TypeUtils.computeGetters(clazz, aliasMap);
+ List getters = TypeUtils.computeGetters(clazz, aliasMap, false);
String className = getGenClassName(clazz);
@@ -212,8 +211,7 @@ public class ASMSerializerFactory implements Opcodes {
}
{
- List sortedGetters = TypeUtils.computeGetters(clazz, aliasMap);
- Collections.sort(sortedGetters);
+ List sortedGetters = TypeUtils.computeGetters(clazz, aliasMap, true);
// sortField support
Context context = new Context(className);
diff --git a/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java
index 38c2ab144..a4a0eb3c3 100644
--- a/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java
+++ b/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java
@@ -20,7 +20,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -60,18 +59,26 @@ public class JavaBeanSerializer implements ObjectSerializer {
}
public JavaBeanSerializer(Class> clazz, Map aliasMap){
- List getterList = new ArrayList();
-
- List fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap);
-
- for (FieldInfo fieldInfo : fieldInfoList) {
- getterList.add(createFieldSerializer(fieldInfo));
+ {
+ List getterList = new ArrayList();
+ List fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap, false);
+
+ for (FieldInfo fieldInfo : fieldInfoList) {
+ getterList.add(createFieldSerializer(fieldInfo));
+ }
+
+ getters = getterList.toArray(new FieldSerializer[getterList.size()]);
+ }
+ {
+ List getterList = new ArrayList();
+ List fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap, true);
+
+ for (FieldInfo fieldInfo : fieldInfoList) {
+ getterList.add(createFieldSerializer(fieldInfo));
+ }
+
+ sortedGetters = getterList.toArray(new FieldSerializer[getterList.size()]);
}
-
- //
- getters = getterList.toArray(new FieldSerializer[getterList.size()]);
- sortedGetters = getterList.toArray(new FieldSerializer[getterList.size()]);
- Arrays.sort(sortedGetters);
}
protected boolean isWriteClassName(JSONSerializer serializer, Object obj, Type fieldType, Object fieldName) {
diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java
index b4d49f17a..d038cc675 100644
--- a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java
+++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java
@@ -685,7 +685,7 @@ public final class SerializeWriter extends Writer {
continue;
}
- if (CharTypes.isEmoji(ch)) {
+ if (ch >= 127) {
lastSpecialIndex = i;
newcount += 5;
continue;
@@ -728,7 +728,7 @@ public final class SerializeWriter extends Writer {
continue;
}
- if (CharTypes.isEmoji(ch)) {
+ if (ch >= 127) {
System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1);
buf[i] = '\\';
buf[i + 1] = 'u';
diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java
index ee38ba00f..72f4d526b 100644
--- a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java
+++ b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java
@@ -102,7 +102,12 @@ public enum SerializerFeature {
/**
* @since 1.1.19
*/
- DisableCheckSpecialChar
+ DisableCheckSpecialChar,
+
+ /**
+ * @since 1.1.20
+ */
+ NonDefault,
;
private SerializerFeature(){
diff --git a/src/main/java/com/alibaba/fastjson/util/TypeUtils.java b/src/main/java/com/alibaba/fastjson/util/TypeUtils.java
index 4c6b389ea..619eafa01 100644
--- a/src/main/java/com/alibaba/fastjson/util/TypeUtils.java
+++ b/src/main/java/com/alibaba/fastjson/util/TypeUtils.java
@@ -29,6 +29,7 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
@@ -39,6 +40,7 @@ import java.util.Map;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
@@ -749,10 +751,12 @@ public class TypeUtils {
return clazz;
}
-
- public static List computeGetters(Class> clazz, Map aliasMap) {
- List fieldInfoList = new ArrayList();
-
+ public static List computeGetters(Class> clazz,
+ Map aliasMap) {
+ return computeGetters(clazz, aliasMap, true);
+ }
+
+ public static List computeGetters(Class> clazz, Map aliasMap, boolean sorted) {
Map fieldInfoMap = new LinkedHashMap();
for (Method method : clazz.getMethods()) {
@@ -885,8 +889,41 @@ public class TypeUtils {
}
}
- for (FieldInfo fieldInfo : fieldInfoMap.values()) {
- fieldInfoList.add(fieldInfo);
+ List fieldInfoList = new ArrayList();
+
+ boolean containsAll = false;
+ String[] orders = null;
+
+ JSONType annotation = clazz.getAnnotation(JSONType.class);
+ if (annotation != null) {
+ orders = annotation.orders();
+
+ if (orders != null && orders.length == fieldInfoMap.size()) {
+ containsAll = true;
+ for (String item : orders) {
+ if (!fieldInfoMap.containsKey(item)) {
+ containsAll = false;
+ break;
+ }
+ }
+ } else {
+ containsAll = false;
+ }
+ }
+
+ if (containsAll) {
+ for (String item : orders) {
+ FieldInfo fieldInfo = fieldInfoMap.get(item);
+ fieldInfoList.add(fieldInfo);
+ }
+ } else {
+ for (FieldInfo fieldInfo : fieldInfoMap.values()) {
+ fieldInfoList.add(fieldInfo);
+ }
+
+ if (sorted) {
+ Collections.sort(fieldInfoList);
+ }
}
return fieldInfoList;
diff --git a/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java b/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java
new file mode 100644
index 000000000..11b0d5f2e
--- /dev/null
+++ b/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java
@@ -0,0 +1,132 @@
+package com.alibaba.json.bvt;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.annotation.JSONType;
+
+public class JSONTypeTest extends TestCase {
+ public void test_0() throws Exception {
+ VO vo = new VO();
+ vo.setId(1001);
+ vo.setName("xx");
+ vo.setAge(33);
+
+ Assert.assertEquals("{\"age\":33,\"id\":1001,\"name\":\"xx\"}",
+ JSON.toJSONString(vo));
+ }
+
+ public void test_1() throws Exception {
+ V1 vo = new V1();
+ vo.setId(1001);
+ vo.setName("xx");
+ vo.setAge(33);
+
+ Assert.assertEquals("{\"id\":1001,\"name\":\"xx\",\"age\":33}",
+ JSON.toJSONString(vo));
+ }
+
+ public void test_2() throws Exception {
+ V1 vo = new V1();
+ vo.setId(1001);
+ vo.setName("xx");
+ vo.setAge(33);
+
+ Assert.assertEquals("{\"id\":1001,\"name\":\"xx\",\"age\":33}",
+ JSON.toJSONString(vo));
+ }
+
+ @JSONType
+ public static class VO {
+ private int id;
+ private String name;
+ private int age;
+
+ 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 int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+
+ @JSONType(orders = { "id", "name", "age" })
+ public static class V1 {
+ private int id;
+ private String name;
+ private int age;
+
+ 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 int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+
+ @JSONType(orders = { "id", "name", "age" },asm=false)
+ private class V2 {
+ private int id;
+ private String name;
+ private int age;
+
+ 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 int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+}
diff --git a/src/test/java/com/alibaba/json/bvt/TestForEmoji.java b/src/test/java/com/alibaba/json/bvt/TestForEmoji.java
index bcf9a7d12..44db296e1 100644
--- a/src/test/java/com/alibaba/json/bvt/TestForEmoji.java
+++ b/src/test/java/com/alibaba/json/bvt/TestForEmoji.java
@@ -21,4 +21,8 @@ public class TestForEmoji extends TestCase {
Assert.assertEquals("\"\\uE001\"", JSON.toJSONString("\uE001", SerializerFeature.BrowserCompatible));
//E507
}
+
+ public void test_zh() throws Exception {
+ Assert.assertEquals("\"\\u4E2D\\u56FD\"", JSON.toJSONString("中国", SerializerFeature.BrowserCompatible));
+ }
}
diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java
index 362abe480..2d425522d 100644
--- a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java
+++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java
@@ -2,9 +2,8 @@ package com.alibaba.json.test.benchmark;
import junit.framework.TestCase;
-import com.alibaba.json.test.benchmark.encode.EishayEncode;
+import com.alibaba.json.test.benchmark.decode.EishayDecode;
import com.alibaba.json.test.codec.FastjsonCodec;
-import com.alibaba.json.test.codec.JacksonCodec;
public class BenchmarkTest extends TestCase {
@@ -15,6 +14,7 @@ public class BenchmarkTest extends TestCase {
executor.setExecuteCount(6);
executor.getCodecList().add(new FastjsonCodec());
// executor.getCodecList().add(new JacksonCodec());
+// executor.getCodecList().add(new Jackson2Codec());
//
// executor.getCodecList().add(new SimpleJsonCodec());
// executor.getCodecList().add(new JsonLibCodec());
@@ -24,10 +24,10 @@ public class BenchmarkTest extends TestCase {
// executor.getCaseList().add(new EishayDecodeBytes());
// executor.getCaseList().add(new EishayDecode2Bytes());
-// executor.getCaseList().add(new EishayDecode());
+ executor.getCaseList().add(new EishayDecode());
// executor.getCaseList().add(new EishayDecodeByClassName());
// executor.getCaseList().add(new EishayTreeDecode());
- executor.getCaseList().add(new EishayEncode());
+// executor.getCaseList().add(new EishayEncode());
// executor.getCaseList().add(new EishayEncodeManual());
// executor.getCaseList().add(new IntArray1000Decode());
// executor.getCaseList().add(new StringArray1000Decode());
diff --git a/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java b/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java
new file mode 100644
index 000000000..c0e58ce9f
--- /dev/null
+++ b/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java
@@ -0,0 +1,63 @@
+package com.alibaba.json.test.codec;
+
+import java.util.Collection;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+
+public class Jackson2Codec implements Codec {
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ public String getName() {
+ return "jackson2";
+ }
+
+ public final T decodeObject(String text, Class clazz) {
+ try {
+ return mapper.readValue(text, clazz);
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+
+ public T decodeObject(byte[] input, Class clazz) throws Exception {
+ try {
+ return mapper.readValue(input, clazz);
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public Collection decodeArray(String text, Class clazz) throws Exception {
+ try {
+ return (Collection) mapper.readValue(text, new TypeReference() {
+ });
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public final Object decodeObject(String text) {
+ try {
+ return (ObjectNode) mapper.readTree(text);
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public Object decode(String text) {
+ try {
+ return mapper.readTree(text);
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public String encode(Object object) throws Exception {
+ return mapper.writeValueAsString(object);
+ }
+}