mirror of
https://github.com/alibaba/fastjson.git
synced 2026-10-21 16:56:28 +08:00
support JSONType.orders
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.1.19</version>
|
||||
<version>1.1.20-SNAPSHOT</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<name>fastjson</name>
|
||||
@@ -186,6 +186,13 @@
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-lgpl</artifactId>
|
||||
|
||||
@@ -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<FieldInfo> getters = TypeUtils.computeGetters(clazz, aliasMap);
|
||||
List<FieldInfo> getters = TypeUtils.computeGetters(clazz, aliasMap, false);
|
||||
|
||||
String className = getGenClassName(clazz);
|
||||
|
||||
@@ -212,8 +211,7 @@ public class ASMSerializerFactory implements Opcodes {
|
||||
}
|
||||
|
||||
{
|
||||
List<FieldInfo> sortedGetters = TypeUtils.computeGetters(clazz, aliasMap);
|
||||
Collections.sort(sortedGetters);
|
||||
List<FieldInfo> sortedGetters = TypeUtils.computeGetters(clazz, aliasMap, true);
|
||||
|
||||
// sortField support
|
||||
Context context = new Context(className);
|
||||
|
||||
@@ -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<String, String> aliasMap){
|
||||
List<FieldSerializer> getterList = new ArrayList<FieldSerializer>();
|
||||
|
||||
List<FieldInfo> fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap);
|
||||
|
||||
for (FieldInfo fieldInfo : fieldInfoList) {
|
||||
getterList.add(createFieldSerializer(fieldInfo));
|
||||
{
|
||||
List<FieldSerializer> getterList = new ArrayList<FieldSerializer>();
|
||||
List<FieldInfo> fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap, false);
|
||||
|
||||
for (FieldInfo fieldInfo : fieldInfoList) {
|
||||
getterList.add(createFieldSerializer(fieldInfo));
|
||||
}
|
||||
|
||||
getters = getterList.toArray(new FieldSerializer[getterList.size()]);
|
||||
}
|
||||
{
|
||||
List<FieldSerializer> getterList = new ArrayList<FieldSerializer>();
|
||||
List<FieldInfo> 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) {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -102,7 +102,12 @@ public enum SerializerFeature {
|
||||
/**
|
||||
* @since 1.1.19
|
||||
*/
|
||||
DisableCheckSpecialChar
|
||||
DisableCheckSpecialChar,
|
||||
|
||||
/**
|
||||
* @since 1.1.20
|
||||
*/
|
||||
NonDefault,
|
||||
;
|
||||
|
||||
private SerializerFeature(){
|
||||
|
||||
@@ -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<FieldInfo> computeGetters(Class<?> clazz, Map<String, String> aliasMap) {
|
||||
List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
|
||||
|
||||
public static List<FieldInfo> computeGetters(Class<?> clazz,
|
||||
Map<String, String> aliasMap) {
|
||||
return computeGetters(clazz, aliasMap, true);
|
||||
}
|
||||
|
||||
public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String, String> aliasMap, boolean sorted) {
|
||||
Map<String, FieldInfo> fieldInfoMap = new LinkedHashMap<String, FieldInfo>();
|
||||
|
||||
for (Method method : clazz.getMethods()) {
|
||||
@@ -885,8 +889,41 @@ public class TypeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
for (FieldInfo fieldInfo : fieldInfoMap.values()) {
|
||||
fieldInfoList.add(fieldInfo);
|
||||
List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
|
||||
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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> T decodeObject(String text, Class<T> clazz) {
|
||||
try {
|
||||
return mapper.readValue(text, clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public <T> T decodeObject(byte[] input, Class<T> clazz) throws Exception {
|
||||
try {
|
||||
return mapper.readValue(input, clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Collection<T> decodeArray(String text, Class<T> clazz) throws Exception {
|
||||
try {
|
||||
return (Collection<T>) mapper.readValue(text, new TypeReference<T>() {
|
||||
});
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user