Skip to content

Commit

Permalink
bug fix for JSONArray toJavaList
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed May 21, 2022
1 parent 1be5718 commit eb6a244
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 4 deletions.
20 changes: 19 additions & 1 deletion core/src/main/java/com/alibaba/fastjson2/JSONArray.java
Expand Up @@ -942,6 +942,12 @@ public <T> T to(Type type) {
return objectReader.createInstance(this);
}

public <T> T to(Class<T> type) {
ObjectReaderProvider provider = JSONFactory.getDefaultObjectReaderProvider();
ObjectReader<T> objectReader = provider.getObjectReader(type);
return objectReader.createInstance(this);
}

/**
* Convert this {@link JSONArray} to the specified Object
*
Expand Down Expand Up @@ -984,13 +990,25 @@ public <T> List<T> toList(Class<T> clazz, JSONReader.Feature... features) {
List<T> list = new ArrayList<>(size());
for (int i = 0; i < this.size(); i++) {
Object item = this.get(i);
T classItem;

T classItem;
if (item instanceof JSONObject) {
classItem = (T) objectReader.createInstance((Map) item, featuresValue);
} else if (item instanceof Map) {
classItem = (T) objectReader.createInstance((Map) item, featuresValue);
} else {
if (item == null) {
list.add(null);
continue;
}

Function typeConvert = provider.getTypeConvert(item.getClass(), clazz);
if (typeConvert != null) {
Object converted = typeConvert.apply(item);
list.add((T) converted);
continue;
}

throw new JSONException(
(item == null ? "null" : item.getClass()) + " cannot be converted to " + clazz
);
Expand Down
Expand Up @@ -136,6 +136,21 @@ public void init(ObjectReaderProvider provider) {
{
// cast to char
provider.registerTypeConvert(Character.class, char.class, o -> o);

Class[] classes = new Class[] {
Byte.class,
Short.class,
Integer.class,
Long.class,
Number.class,
Float.class,
Double.class,
BigInteger.class,
BigDecimal.class,
};
for (Class type : classes) {
provider.registerTypeConvert(type, String.class, TO_STRING);
}
}

{
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/reader/TypeConverts.java
Expand Up @@ -20,6 +20,17 @@ public class TypeConverts {
public static final Function<Number, Float> NUMBER_TO_FLOAT = o -> o == null ? null : o.floatValue();
public static final Function<Number, Float> NUMBER_TO_FLOAT_VALUE = o -> o == null ? 0F : o.floatValue();
public static final Function<BigDecimal, Integer> DECIMAL_TO_INTEGER = o -> o == null ? null : ((BigDecimal) o).intValueExact();
public static final Function<Object, String> TO_STRING = new ToString();

static class ToString implements Function {
@Override
public Object apply(Object o) {
if (o == null) {
return null;
}
return o.toString();
}
}

static class StringToAny implements Function {
final Object defaultValue;
Expand Down
29 changes: 29 additions & 0 deletions core/src/test/java/com/alibaba/fastjson2/issues/Issue296.java
@@ -0,0 +1,29 @@
package com.alibaba.fastjson2.issues;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue296 {
@Test
public void test() {
List<String> list = JSON.parseArray("[1]").toList(String.class);
assertEquals(1, list.size());
assertEquals("1", list.get(0));

String[] values = JSONObject.of("values", JSONArray.of(1, 2L)).getObject("values", String[].class);
assertEquals(2, values.length);
assertEquals("1", values[0]);
assertEquals("2", values[1]);

int[] array = JSONArray.of("1", "2").to(int[].class);
assertEquals(2, array.length);
assertEquals(1, array[0]);
assertEquals(2, array[1]);
}
}
Expand Up @@ -14,7 +14,6 @@
import java.util.function.Function;

public class JSONArray extends JSON implements List {
static ObjectWriter<JSONArray> arrayWriter;
static ObjectReader<JSONArray> arrayReader;
static ObjectReader<JSONObject> objectReader;

Expand Down Expand Up @@ -800,7 +799,21 @@ public <T> List<T> toJavaList(Class<T> clazz) {
if (item instanceof Map) {
classItem = (T) objectReader.createInstance((Map) item, 0L);
} else {
throw new JSONException("TODO");
if (item == null) {
list.add(null);
continue;
}

Function typeConvert = provider.getTypeConvert(item.getClass(), clazz);
if (typeConvert != null) {
Object converted = typeConvert.apply(item);
list.add((T) converted);
continue;
}

throw new com.alibaba.fastjson2.JSONException(
(item == null ? "null" : item.getClass()) + " cannot be converted to " + clazz
);
}
list.add(classItem);
}
Expand All @@ -814,7 +827,9 @@ public JSONArray fluentAdd(Object e) {
}

public <T> T toJavaObject(Class<T> clazz) {
return com.alibaba.fastjson2.JSON.toJavaObject(this, clazz);
ObjectReaderProvider provider = JSONFactory.getDefaultObjectReaderProvider();
ObjectReader<T> objectReader = provider.getObjectReader(clazz);
return objectReader.createInstance(this);
}

@Override
Expand Down
@@ -0,0 +1,27 @@
package com.alibaba.fastjson.issues_compatible;

import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue296 {
@Test
public void test() {
List<String> list = JSON.parseArray("[1]").toJavaList(String.class);
assertEquals(1, list.size());
assertEquals("1", list.get(0));

String[] values = JSON.parseObject("{\"values\":[1,2]}").getObject("values", String[].class);
assertEquals(2, values.length);
assertEquals("1", values[0]);
assertEquals("2", values[1]);

int[] array = JSON.parseArray("[\"1\",\"2\"]").toJavaObject(int[].class);
assertEquals(2, array.length);
assertEquals(1, array[0]);
assertEquals(2, array[1]);
}
}

0 comments on commit eb6a244

Please sign in to comment.