diff --git a/core/src/main/java/com/alibaba/fastjson2/util/TypeUtils.java b/core/src/main/java/com/alibaba/fastjson2/util/TypeUtils.java index c7ad8ee294..31f7257e5c 100644 --- a/core/src/main/java/com/alibaba/fastjson2/util/TypeUtils.java +++ b/core/src/main/java/com/alibaba/fastjson2/util/TypeUtils.java @@ -4108,4 +4108,20 @@ public static Type getMapValueType(Type fieldType) { } return Object.class; } + + public static List toList(Object object) { + if (object == null) { + return null; + } else if (object instanceof List) { + return (List) object; + } else if (object instanceof Iterable) { + List list = new ArrayList(); + for (Object item : (Iterable) object) { + list.add(item); + } + return list; + } else { + throw new JSONException("Can not cast '" + object.getClass() + "' to List"); + } + } } diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListFunc.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListFunc.java index 566c18235a..6cb556475d 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListFunc.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListFunc.java @@ -8,6 +8,7 @@ import java.util.function.Function; import static com.alibaba.fastjson2.JSONWriter.Feature.*; +import static com.alibaba.fastjson2.util.TypeUtils.toList; final class FieldWriterListFunc extends FieldWriterList { @@ -39,7 +40,7 @@ public Object getFieldValue(T object) { public boolean write(JSONWriter jsonWriter, T object) { List value; try { - value = function.apply(object); + value = toList(function.apply(object)); } catch (RuntimeException error) { if (jsonWriter.isIgnoreErrorGetter()) { return false; @@ -80,7 +81,7 @@ public boolean write(JSONWriter jsonWriter, T object) { @Override public void writeValue(JSONWriter jsonWriter, T object) { - List list = function.apply(object); + List list = toList(function.apply(object)); if (list == null) { jsonWriter.writeNull(); return; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListMethod.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListMethod.java index 7d17e25750..d42a39ac30 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListMethod.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListMethod.java @@ -10,6 +10,7 @@ import java.util.List; import static com.alibaba.fastjson2.JSONWriter.Feature.*; +import static com.alibaba.fastjson2.util.TypeUtils.toList; final class FieldWriterListMethod extends FieldWriterList { @@ -42,7 +43,7 @@ public Object getFieldValue(Object object) { public boolean write(JSONWriter jsonWriter, T object) { List value; try { - value = (List) getFieldValue(object); + value = toList(getFieldValue(object)); } catch (JSONException error) { if (jsonWriter.isIgnoreErrorGetter()) { return false; @@ -87,7 +88,7 @@ public boolean write(JSONWriter jsonWriter, T object) { @Override public void writeValue(JSONWriter jsonWriter, T object) { - List value = (List) getFieldValue(object); + List value = toList(getFieldValue(object)); if (value == null) { jsonWriter.writeNull(); diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListStrFunc.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListStrFunc.java index 80e10d5552..f4b1b537a4 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListStrFunc.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterListStrFunc.java @@ -8,6 +8,7 @@ import java.util.function.Function; import static com.alibaba.fastjson2.JSONWriter.Feature.*; +import static com.alibaba.fastjson2.util.TypeUtils.toList; final class FieldWriterListStrFunc extends FieldWriter { @@ -37,7 +38,7 @@ public Object getFieldValue(T object) { public boolean write(JSONWriter jsonWriter, T object) { List list; try { - list = function.apply(object); + list = toList(function.apply(object)); } catch (RuntimeException error) { if (jsonWriter.isIgnoreErrorGetter()) { return false; @@ -97,7 +98,7 @@ public boolean write(JSONWriter jsonWriter, T object) { @Override public void writeValue(JSONWriter jsonWriter, T object) { - List list = function.apply(object); + List list = toList(function.apply(object)); if (list == null) { jsonWriter.writeNull(); return; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreator.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreator.java index 4576ef9bc4..4c4606a473 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreator.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreator.java @@ -730,7 +730,7 @@ public FieldWriter createFieldWriter( } } - if (fieldClass == List.class || fieldClass == ArrayList.class) { + if (fieldClass == List.class || fieldClass == ArrayList.class || fieldClass == Iterable.class) { Type itemType = null; if (fieldType instanceof ParameterizedType) { itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0]; @@ -894,7 +894,7 @@ public FieldWriter createFieldWriter( return new FieldWriterStringMethod(fieldName, ordinal, format, label, features, field, method); } - if (fieldClass == List.class) { + if (fieldClass == List.class || fieldClass == ArrayList.class || fieldClass == Iterable.class) { Type itemType; if (fieldType instanceof ParameterizedType) { itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0]; @@ -1076,7 +1076,7 @@ public FieldWriter createFieldWriter( Type rawType = parameterizedType.getRawType(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); - if (rawType == List.class || rawType == ArrayList.class) { + if (rawType == List.class || rawType == ArrayList.class || rawType == Iterable.class) { if (actualTypeArguments.length == 1) { Type itemType = actualTypeArguments[0]; if (itemType == String.class) { diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java index 812fc6089b..7bbc365c34 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java @@ -67,7 +67,7 @@ public void writeArrayMappingJSONB(JSONWriter jsonWriter, Object object, Object return; } - List list = (List) object; + List list = toList(object); Class previousClass = null; ObjectWriter previousObjectWriter = null; @@ -131,7 +131,7 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T } } - List list = (List) object; + List list = toList(object); Class previousClass = null; ObjectWriter previousObjectWriter = null; @@ -238,8 +238,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f return; } - List list = (List) object; - + List list = toList(object); Class previousClass = null; ObjectWriter previousObjectWriter = null; boolean previousRefDetect = true; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListEnum.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListEnum.java index ef45a99c34..0e3c36c117 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListEnum.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListEnum.java @@ -6,6 +6,8 @@ import java.lang.reflect.Type; import java.util.List; +import static com.alibaba.fastjson2.util.TypeUtils.toList; + final class ObjectWriterImplListEnum extends ObjectWriterPrimitiveImpl { final Class defineClass; @@ -32,7 +34,7 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T jsonWriter.writeTypeName(TypeUtils.getTypeName(objectClass)); } - List list = (List) object; + List list = toList(object); int size = list.size(); jsonWriter.startArray(size); @@ -69,7 +71,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f return; } - List list = (List) object; + List list = toList(object); jsonWriter.startArray(); for (int i = 0; i < list.size(); i++) { diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListStr.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListStr.java index d0dbe13940..1d109d43ef 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListStr.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplListStr.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; +import static com.alibaba.fastjson2.util.TypeUtils.toList; import static com.alibaba.fastjson2.writer.ObjectWriterImplList.CLASS_SUBLIST; final class ObjectWriterImplListStr @@ -21,7 +22,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f return; } - List list = (List) object; + List list = toList(object); jsonWriter.startArray(); for (int i = 0; i < list.size(); i++) { @@ -68,7 +69,7 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T ); } - List list = (List) object; + List list = toList(object); jsonWriter.writeString(list); } } diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_1500/Issue1563.java b/core/src/test/java/com/alibaba/fastjson2/issues_1500/Issue1563.java new file mode 100644 index 0000000000..82e544864c --- /dev/null +++ b/core/src/test/java/com/alibaba/fastjson2/issues_1500/Issue1563.java @@ -0,0 +1,70 @@ +package com.alibaba.fastjson2.issues_1500; + +import com.alibaba.fastjson2.JSON; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class Issue1563 { + @Test + public void test() { + List> data = new ArrayList<>(); + List strData = new ArrayList<>(); + for (int i = 0; i < 2; i++) { + List row = new ArrayList<>(); + for (int j = 0; j < 2; j++) { + String str = "i_" + i + "_j_" + j; + row.add(str); + strData.add(str); + } + data.add(row); + } + MyData myData = new MyData(data, strData); + assertEquals("{\"data\":[[\"i_0_j_0\",\"i_0_j_1\"],[\"i_1_j_0\",\"i_1_j_1\"]],\"strData\":[\"i_0_j_0\",\"i_0_j_1\",\"i_1_j_0\",\"i_1_j_1\"]}", + JSON.toJSONString(myData)); + } + + public static class MyData { + private final List> list; + private final List strList; + + public MyData(List> list, List strList) { + this.list = list; + this.strList = strList; + } + + public Iterable getData() { + Iterator> it = list.iterator(); + return () -> new Iterator() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public Object next() { + return it.next(); + } + }; + } + + public Iterable getStrData() { + Iterator it = strList.iterator(); + return () -> new Iterator() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public String next() { + return it.next(); + } + }; + } + } +}