mirror of
https://github.com/alibaba/fastjson.git
synced 2026-10-23 09:58:34 +08:00
improved for BeanToArray
This commit is contained in:
@@ -5,6 +5,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
|
||||
/**
|
||||
@@ -21,6 +22,7 @@ public @interface JSONType {
|
||||
String[] ignores() default {};
|
||||
|
||||
SerializerFeature[] serialzeFeatures() default {};
|
||||
Feature[] parseFeatures() default {};
|
||||
|
||||
boolean alphabetic() default true;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.fastjson.parser;
|
||||
|
||||
|
||||
/**
|
||||
* @author wenshao[szujobs@hotmail.com]
|
||||
*/
|
||||
@@ -109,4 +110,18 @@ public enum Feature {
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
public static int of(Feature[] features) {
|
||||
if (features == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int value = 0;
|
||||
|
||||
for (Feature feature: features) {
|
||||
value |= feature.getMask();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,6 +323,14 @@ public class ASMDeserializerFactory implements Opcodes {
|
||||
|
||||
{
|
||||
Label next_ = new Label();
|
||||
|
||||
mw.visitVarInsn(ALOAD, 0);
|
||||
mw.visitVarInsn(ALOAD, context.var("lexer"));
|
||||
mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "isSupportArrayToBean",
|
||||
"(Lcom/alibaba/fastjson/parser/JSONLexer;)Z");
|
||||
mw.visitJumpInsn(IFEQ, next_);
|
||||
//isSupportArrayToBean
|
||||
|
||||
mw.visitVarInsn(ALOAD, context.var("lexer"));
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "token", "()I");
|
||||
mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "LBRACKET", "I");
|
||||
|
||||
@@ -90,6 +90,10 @@ public abstract class ASMJavaBeanDeserializer implements ObjectDeserializer {
|
||||
return ASMJavaBeanDeserializer.this.createFieldDeserializer(mapping, clazz, fieldInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSupportArrayToBean(JSONLexer lexer) {
|
||||
return serializer.isSupportArrayToBean(lexer);
|
||||
}
|
||||
|
||||
public Object parseRest(DefaultJSONParser parser, Type type, Object fieldName, Object instance) {
|
||||
// serializer.parseField(parser, key, object, objectType, fieldValues)
|
||||
|
||||
@@ -193,7 +193,7 @@ public class JavaBeanDeserializer implements ObjectDeserializer {
|
||||
return (T) object;
|
||||
}
|
||||
|
||||
if (lexer.token() == JSONToken.LBRACKET && lexer.isEnabled(Feature.SupportArrayToBean)) {
|
||||
if (lexer.token() == JSONToken.LBRACKET && isSupportArrayToBean(lexer)) {
|
||||
return deserialzeArrayMapping(parser, type, fieldName, object);
|
||||
}
|
||||
|
||||
@@ -428,4 +428,8 @@ public class JavaBeanDeserializer implements ObjectDeserializer {
|
||||
public List<FieldDeserializer> getSortedFieldDeserializers() {
|
||||
return sortedFieldDeserializers;
|
||||
}
|
||||
|
||||
public final boolean isSupportArrayToBean(JSONLexer lexer) {
|
||||
return Feature.isEnabled(beanInfo.getParserFeatures(), Feature.SupportArrayToBean) || lexer.isEnabled(Feature.SupportArrayToBean);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,11 +467,11 @@ public class ASMSerializerFactory implements Opcodes {
|
||||
{
|
||||
Label endWriteAsArray_ = new Label();
|
||||
|
||||
mw.visitVarInsn(ALOAD, 0);
|
||||
mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", getDesc(JavaBeanSerializer.class));
|
||||
mw.visitVarInsn(ALOAD, context.serializer());
|
||||
mw.visitVarInsn(ALOAD, context.obj());
|
||||
mw.visitVarInsn(ALOAD, context.paramFieldType());
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "isWriteAsArray",
|
||||
"(Ljava/lang/Object;Ljava/lang/reflect/Type;)Z");
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JavaBeanSerializer.class), "isWriteAsArray",
|
||||
"(Lcom/alibaba/fastjson/serializer/JSONSerializer;)Z");
|
||||
mw.visitJumpInsn(IFEQ, endWriteAsArray_);
|
||||
|
||||
// /////
|
||||
|
||||
@@ -537,14 +537,4 @@ public class JSONSerializer {
|
||||
this.out.close();
|
||||
}
|
||||
|
||||
public final boolean isWriteAsArray(Object object, Type fieldType) {
|
||||
boolean writeAsArray;
|
||||
if (out.isEnabled(SerializerFeature.BeanToArray)) {
|
||||
writeAsArray = true;
|
||||
} else {
|
||||
writeAsArray = false;
|
||||
}
|
||||
|
||||
return writeAsArray;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.alibaba.fastjson.annotation.JSONType;
|
||||
import com.alibaba.fastjson.util.FieldInfo;
|
||||
import com.alibaba.fastjson.util.TypeUtils;
|
||||
|
||||
@@ -114,7 +113,7 @@ public class JavaBeanSerializer implements ObjectSerializer {
|
||||
SerialContext parent = serializer.getContext();
|
||||
serializer.setContext(parent, object, fieldName, features);
|
||||
|
||||
final boolean writeAsArray = serializer.isWriteAsArray(object, fieldType);
|
||||
final boolean writeAsArray = isWriteAsArray(serializer);
|
||||
|
||||
try {
|
||||
final char startSeperator = writeAsArray ? '[' : '{';
|
||||
@@ -263,4 +262,19 @@ public class JavaBeanSerializer implements ObjectSerializer {
|
||||
|
||||
return new ObjectFieldSerializer(fieldInfo);
|
||||
}
|
||||
|
||||
public boolean isWriteAsArray(JSONSerializer serializer) {
|
||||
if (SerializerFeature.isEnabled(features, SerializerFeature.BeanToArray)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean writeAsArray;
|
||||
if (serializer.isEnabled(SerializerFeature.BeanToArray)) {
|
||||
writeAsArray = true;
|
||||
} else {
|
||||
writeAsArray = false;
|
||||
}
|
||||
|
||||
return writeAsArray;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,12 @@ public class DeserializeBeanInfo {
|
||||
private final List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
private final List<FieldInfo> sortedFieldList = new ArrayList<FieldInfo>();
|
||||
|
||||
private int parserFeatures = 0;
|
||||
|
||||
public DeserializeBeanInfo(Class<?> clazz){
|
||||
super();
|
||||
this.clazz = clazz;
|
||||
this.parserFeatures = TypeUtils.getParserFeatures(clazz);
|
||||
}
|
||||
|
||||
public Constructor<?> getDefaultConstructor() {
|
||||
@@ -125,7 +128,8 @@ public class DeserializeBeanInfo {
|
||||
Field field = TypeUtils.getField(clazz, fieldAnnotation.name());
|
||||
final int ordinal = fieldAnnotation.ordinal();
|
||||
final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
|
||||
FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures);
|
||||
FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field,
|
||||
ordinal, serialzeFeatures);
|
||||
beanInfo.add(fieldInfo);
|
||||
}
|
||||
return beanInfo;
|
||||
@@ -199,10 +203,10 @@ public class DeserializeBeanInfo {
|
||||
if (!annotation.deserialize()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ordinal = annotation.ordinal();
|
||||
serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
|
||||
|
||||
|
||||
if (annotation.name().length() != 0) {
|
||||
String propertyName = annotation.name();
|
||||
beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures));
|
||||
@@ -228,7 +232,7 @@ public class DeserializeBeanInfo {
|
||||
propertyName = methodName.substring(4);
|
||||
} else if (c3 == 'f') {
|
||||
propertyName = methodName.substring(3);
|
||||
} else if (methodName.length()>=5 && Character.isUpperCase(methodName.charAt(4))){
|
||||
} else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) {
|
||||
propertyName = TypeUtils.decapitalize(methodName.substring(3));
|
||||
} else {
|
||||
continue;
|
||||
@@ -242,11 +246,11 @@ public class DeserializeBeanInfo {
|
||||
|
||||
if (field != null) {
|
||||
JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
|
||||
|
||||
|
||||
if (fieldAnnotation != null) {
|
||||
ordinal = fieldAnnotation.ordinal();
|
||||
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
|
||||
|
||||
|
||||
if (fieldAnnotation.name().length() != 0) {
|
||||
propertyName = fieldAnnotation.name();
|
||||
beanInfo.add(new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures));
|
||||
@@ -285,7 +289,7 @@ public class DeserializeBeanInfo {
|
||||
if (fieldAnnotation != null) {
|
||||
ordinal = fieldAnnotation.ordinal();
|
||||
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
|
||||
|
||||
|
||||
if (fieldAnnotation.name().length() != 0) {
|
||||
propertyName = fieldAnnotation.name();
|
||||
}
|
||||
@@ -400,4 +404,8 @@ public class DeserializeBeanInfo {
|
||||
return factoryMethod;
|
||||
}
|
||||
|
||||
|
||||
public int getParserFeatures() {
|
||||
return parserFeatures;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ 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.Feature;
|
||||
import com.alibaba.fastjson.parser.JSONScanner;
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
|
||||
@@ -1319,6 +1320,16 @@ public class TypeUtils {
|
||||
return SerializerFeature.of(annotation.serialzeFeatures());
|
||||
}
|
||||
|
||||
public static int getParserFeatures(Class<?> clazz) {
|
||||
JSONType annotation = clazz.getAnnotation(JSONType.class);
|
||||
|
||||
if (annotation == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Feature.of(annotation.parseFeatures());
|
||||
}
|
||||
|
||||
public static String decapitalize(String name) {
|
||||
if (name == null || name.length() == 0) {
|
||||
return name;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.alibaba.json.bvt.writeAsArray;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.alibaba.fastjson.annotation.JSONType;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
|
||||
public class WriteAsArray_jsonType extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
VO vo = new VO();
|
||||
vo.setId(123);
|
||||
vo.setName("wenshao");
|
||||
|
||||
Parent parent = new Parent();
|
||||
parent.setVo(vo);
|
||||
|
||||
String text = JSON.toJSONString(parent);
|
||||
Assert.assertEquals("{\"vo\":[123,\"wenshao\"]}", text);
|
||||
VO vo2 = JSON.parseObject(text, Parent.class).getVo();
|
||||
Assert.assertEquals(vo.getId(), vo2.getId());
|
||||
Assert.assertEquals(vo.getName(), vo2.getName());
|
||||
}
|
||||
|
||||
public static class Parent {
|
||||
private VO vo;
|
||||
|
||||
public VO getVo() {
|
||||
return vo;
|
||||
}
|
||||
|
||||
public void setVo(VO vo) {
|
||||
this.vo = vo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@JSONType(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean)
|
||||
public static class VO {
|
||||
@JSONField(ordinal=1)
|
||||
private int id;
|
||||
|
||||
@JSONField(ordinal=2)
|
||||
private String name;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user