Skip to content

Commit 92f7a91

Browse files
committed
improved for BeanToArray
1 parent 895bc33 commit 92f7a91

File tree

11 files changed

+147
-24
lines changed

11 files changed

+147
-24
lines changed

src/main/java/com/alibaba/fastjson/annotation/JSONType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.lang.annotation.RetentionPolicy;
66
import java.lang.annotation.Target;
77

8+
import com.alibaba.fastjson.parser.Feature;
89
import com.alibaba.fastjson.serializer.SerializerFeature;
910

1011
/**
@@ -21,6 +22,7 @@
2122
String[] ignores() default {};
2223

2324
SerializerFeature[] serialzeFeatures() default {};
25+
Feature[] parseFeatures() default {};
2426

2527
boolean alphabetic() default true;
2628

src/main/java/com/alibaba/fastjson/parser/Feature.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.alibaba.fastjson.parser;
1717

18+
1819
/**
1920
* @author wenshao[szujobs@hotmail.com]
2021
*/
@@ -109,4 +110,18 @@ public static int config(int features, Feature feature, boolean state) {
109110

110111
return features;
111112
}
113+
114+
public static int of(Feature[] features) {
115+
if (features == null) {
116+
return 0;
117+
}
118+
119+
int value = 0;
120+
121+
for (Feature feature: features) {
122+
value |= feature.getMask();
123+
}
124+
125+
return value;
126+
}
112127
}

src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,14 @@ void _deserialze(ClassWriter cw, Context context) {
323323

324324
{
325325
Label next_ = new Label();
326+
327+
mw.visitVarInsn(ALOAD, 0);
328+
mw.visitVarInsn(ALOAD, context.var("lexer"));
329+
mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "isSupportArrayToBean",
330+
"(Lcom/alibaba/fastjson/parser/JSONLexer;)Z");
331+
mw.visitJumpInsn(IFEQ, next_);
332+
//isSupportArrayToBean
333+
326334
mw.visitVarInsn(ALOAD, context.var("lexer"));
327335
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "token", "()I");
328336
mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "LBRACKET", "I");

src/main/java/com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class<?>
9090
return ASMJavaBeanDeserializer.this.createFieldDeserializer(mapping, clazz, fieldInfo);
9191
}
9292
}
93+
94+
public boolean isSupportArrayToBean(JSONLexer lexer) {
95+
return serializer.isSupportArrayToBean(lexer);
96+
}
9397

9498
public Object parseRest(DefaultJSONParser parser, Type type, Object fieldName, Object instance) {
9599
// serializer.parseField(parser, key, object, objectType, fieldValues)

src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName, O
193193
return (T) object;
194194
}
195195

196-
if (lexer.token() == JSONToken.LBRACKET && lexer.isEnabled(Feature.SupportArrayToBean)) {
196+
if (lexer.token() == JSONToken.LBRACKET && isSupportArrayToBean(lexer)) {
197197
return deserialzeArrayMapping(parser, type, fieldName, object);
198198
}
199199

@@ -428,4 +428,8 @@ public int getFastMatchToken() {
428428
public List<FieldDeserializer> getSortedFieldDeserializers() {
429429
return sortedFieldDeserializers;
430430
}
431+
432+
public final boolean isSupportArrayToBean(JSONLexer lexer) {
433+
return Feature.isEnabled(beanInfo.getParserFeatures(), Feature.SupportArrayToBean) || lexer.isEnabled(Feature.SupportArrayToBean);
434+
}
431435
}

src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,11 +467,11 @@ private void generateWriteMethod(Class<?> clazz, MethodVisitor mw, List<FieldInf
467467
{
468468
Label endWriteAsArray_ = new Label();
469469

470+
mw.visitVarInsn(ALOAD, 0);
471+
mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", getDesc(JavaBeanSerializer.class));
470472
mw.visitVarInsn(ALOAD, context.serializer());
471-
mw.visitVarInsn(ALOAD, context.obj());
472-
mw.visitVarInsn(ALOAD, context.paramFieldType());
473-
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "isWriteAsArray",
474-
"(Ljava/lang/Object;Ljava/lang/reflect/Type;)Z");
473+
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JavaBeanSerializer.class), "isWriteAsArray",
474+
"(Lcom/alibaba/fastjson/serializer/JSONSerializer;)Z");
475475
mw.visitJumpInsn(IFEQ, endWriteAsArray_);
476476

477477
// /////

src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -537,14 +537,4 @@ public void close() {
537537
this.out.close();
538538
}
539539

540-
public final boolean isWriteAsArray(Object object, Type fieldType) {
541-
boolean writeAsArray;
542-
if (out.isEnabled(SerializerFeature.BeanToArray)) {
543-
writeAsArray = true;
544-
} else {
545-
writeAsArray = false;
546-
}
547-
548-
return writeAsArray;
549-
}
550540
}

src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
import com.alibaba.fastjson.JSON;
2828
import com.alibaba.fastjson.JSONException;
29-
import com.alibaba.fastjson.annotation.JSONType;
3029
import com.alibaba.fastjson.util.FieldInfo;
3130
import com.alibaba.fastjson.util.TypeUtils;
3231

@@ -114,7 +113,7 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty
114113
SerialContext parent = serializer.getContext();
115114
serializer.setContext(parent, object, fieldName, features);
116115

117-
final boolean writeAsArray = serializer.isWriteAsArray(object, fieldType);
116+
final boolean writeAsArray = isWriteAsArray(serializer);
118117

119118
try {
120119
final char startSeperator = writeAsArray ? '[' : '{';
@@ -263,4 +262,19 @@ public FieldSerializer createFieldSerializer(FieldInfo fieldInfo) {
263262

264263
return new ObjectFieldSerializer(fieldInfo);
265264
}
265+
266+
public boolean isWriteAsArray(JSONSerializer serializer) {
267+
if (SerializerFeature.isEnabled(features, SerializerFeature.BeanToArray)) {
268+
return true;
269+
}
270+
271+
boolean writeAsArray;
272+
if (serializer.isEnabled(SerializerFeature.BeanToArray)) {
273+
writeAsArray = true;
274+
} else {
275+
writeAsArray = false;
276+
}
277+
278+
return writeAsArray;
279+
}
266280
}

src/main/java/com/alibaba/fastjson/util/DeserializeBeanInfo.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ public class DeserializeBeanInfo {
3030
private final List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
3131
private final List<FieldInfo> sortedFieldList = new ArrayList<FieldInfo>();
3232

33+
private int parserFeatures = 0;
34+
3335
public DeserializeBeanInfo(Class<?> clazz){
3436
super();
3537
this.clazz = clazz;
38+
this.parserFeatures = TypeUtils.getParserFeatures(clazz);
3639
}
3740

3841
public Constructor<?> getDefaultConstructor() {
@@ -125,7 +128,8 @@ public static DeserializeBeanInfo computeSetters(Class<?> clazz, Type type) {
125128
Field field = TypeUtils.getField(clazz, fieldAnnotation.name());
126129
final int ordinal = fieldAnnotation.ordinal();
127130
final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
128-
FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures);
131+
FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field,
132+
ordinal, serialzeFeatures);
129133
beanInfo.add(fieldInfo);
130134
}
131135
return beanInfo;
@@ -199,10 +203,10 @@ public static DeserializeBeanInfo computeSetters(Class<?> clazz, Type type) {
199203
if (!annotation.deserialize()) {
200204
continue;
201205
}
202-
206+
203207
ordinal = annotation.ordinal();
204208
serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
205-
209+
206210
if (annotation.name().length() != 0) {
207211
String propertyName = annotation.name();
208212
beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures));
@@ -228,7 +232,7 @@ public static DeserializeBeanInfo computeSetters(Class<?> clazz, Type type) {
228232
propertyName = methodName.substring(4);
229233
} else if (c3 == 'f') {
230234
propertyName = methodName.substring(3);
231-
} else if (methodName.length()>=5 && Character.isUpperCase(methodName.charAt(4))){
235+
} else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) {
232236
propertyName = TypeUtils.decapitalize(methodName.substring(3));
233237
} else {
234238
continue;
@@ -242,11 +246,11 @@ public static DeserializeBeanInfo computeSetters(Class<?> clazz, Type type) {
242246

243247
if (field != null) {
244248
JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
245-
249+
246250
if (fieldAnnotation != null) {
247251
ordinal = fieldAnnotation.ordinal();
248252
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
249-
253+
250254
if (fieldAnnotation.name().length() != 0) {
251255
propertyName = fieldAnnotation.name();
252256
beanInfo.add(new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures));
@@ -285,7 +289,7 @@ public static DeserializeBeanInfo computeSetters(Class<?> clazz, Type type) {
285289
if (fieldAnnotation != null) {
286290
ordinal = fieldAnnotation.ordinal();
287291
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
288-
292+
289293
if (fieldAnnotation.name().length() != 0) {
290294
propertyName = fieldAnnotation.name();
291295
}
@@ -400,4 +404,8 @@ public static Method getFactoryMethod(Class<?> clazz) {
400404
return factoryMethod;
401405
}
402406

407+
408+
public int getParserFeatures() {
409+
return parserFeatures;
410+
}
403411
}

src/main/java/com/alibaba/fastjson/util/TypeUtils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import com.alibaba.fastjson.JSONObject;
5252
import com.alibaba.fastjson.annotation.JSONField;
5353
import com.alibaba.fastjson.annotation.JSONType;
54+
import com.alibaba.fastjson.parser.Feature;
5455
import com.alibaba.fastjson.parser.JSONScanner;
5556
import com.alibaba.fastjson.parser.ParserConfig;
5657
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
@@ -1319,6 +1320,16 @@ public static int getSerializeFeatures(Class<?> clazz) {
13191320
return SerializerFeature.of(annotation.serialzeFeatures());
13201321
}
13211322

1323+
public static int getParserFeatures(Class<?> clazz) {
1324+
JSONType annotation = clazz.getAnnotation(JSONType.class);
1325+
1326+
if (annotation == null) {
1327+
return 0;
1328+
}
1329+
1330+
return Feature.of(annotation.parseFeatures());
1331+
}
1332+
13221333
public static String decapitalize(String name) {
13231334
if (name == null || name.length() == 0) {
13241335
return name;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.alibaba.json.bvt.writeAsArray;
2+
3+
import junit.framework.TestCase;
4+
5+
import org.junit.Assert;
6+
7+
import com.alibaba.fastjson.JSON;
8+
import com.alibaba.fastjson.annotation.JSONField;
9+
import com.alibaba.fastjson.annotation.JSONType;
10+
import com.alibaba.fastjson.parser.Feature;
11+
import com.alibaba.fastjson.serializer.SerializerFeature;
12+
13+
public class WriteAsArray_jsonType extends TestCase {
14+
15+
public void test_0() throws Exception {
16+
VO vo = new VO();
17+
vo.setId(123);
18+
vo.setName("wenshao");
19+
20+
Parent parent = new Parent();
21+
parent.setVo(vo);
22+
23+
String text = JSON.toJSONString(parent);
24+
Assert.assertEquals("{\"vo\":[123,\"wenshao\"]}", text);
25+
VO vo2 = JSON.parseObject(text, Parent.class).getVo();
26+
Assert.assertEquals(vo.getId(), vo2.getId());
27+
Assert.assertEquals(vo.getName(), vo2.getName());
28+
}
29+
30+
public static class Parent {
31+
private VO vo;
32+
33+
public VO getVo() {
34+
return vo;
35+
}
36+
37+
public void setVo(VO vo) {
38+
this.vo = vo;
39+
}
40+
41+
}
42+
43+
@JSONType(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean)
44+
public static class VO {
45+
@JSONField(ordinal=1)
46+
private int id;
47+
48+
@JSONField(ordinal=2)
49+
private String name;
50+
51+
public int getId() {
52+
return id;
53+
}
54+
55+
public void setId(int id) {
56+
this.id = id;
57+
}
58+
59+
public String getName() {
60+
return name;
61+
}
62+
63+
public void setName(String name) {
64+
this.name = name;
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)