support JSONType.orders

This commit is contained in:
温少
2012-05-22 09:41:49 +08:00
parent db0261d46d
commit fba2f73681
10 changed files with 283 additions and 30 deletions
+8 -1
View File
@@ -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);
}
}