fastjson
fastjson copied to clipboard
反序列化json的时候,会将数组自动转成map
输入的json字符串如下:
{
"serviceType":"dubbo",
"types":[
{
"enums":[
],
"typeBuilderName":"DefaultTypeBuilder",
"type":"int",
"items":[
],
"properties":{
}
}
]
}
反序列化的类如下:
public final class MainFastJSON {
public static class Type {
public List<String> enums = new ArrayList<>();
public String typeBuilderName = "";
public String type = "";
}
public static class Metadata {
public String serviceType;
public Map<String, Type> types = new HashMap<>();
}
public static void main(String[] args) {
String jsonStr="...";
Metadata m = JSON.parseObject(jsonStr, Metadata.class);
System.out.println("types size:" + m.types.size());
System.out.println(JSON.toJSONString(m));
}
}
types在输入数据中是一个数组,但是反序列化后types变成了一个size为5的map:
{
"serviceType":"dubbo",
"types":{
"enums":[
],
"typeBuilderName":"DefaultTypeBuilder",
"type":"int",
"items":[
],
"properties":{
}
}
}
这种情况,应该抛出反序列化异常,否则会改变数据的结构,会导致后续依赖这些数据的代码出错。
完整示例代码
// MainFastJSON.java
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class MainFastJSON {
public static class Type {
public List<String> enums = new ArrayList<>();
public String typeBuilderName = "";
public String type = "";
}
public static class Metadata {
public String serviceType;
public Map<String, Type> types = new HashMap<>();
}
public static void main(String[] args) {
String jsonStr = "{" +
" \"serviceType\":\"dubbo\"," +
" \"types\":[" +
" {" +
" \"enums\":[" +
"" +
" ]," +
" \"typeBuilderName\":\"DefaultTypeBuilder\"," +
" \"type\":\"int\"," +
" \"items\":[" +
"" +
" ]," +
" \"properties\":{" +
"" +
" }" +
" }" +
" ]" +
"}";
Metadata m = JSON.parseObject(jsonStr, Metadata.class);
System.out.println("types size:" + m.types.size());
System.out.println(JSON.toJSONString(m));
}
}
猜测本意是想作为一个 feature 引入的( 参考fastjson-1.2.32版本发布中的 Map类型的反序列化支持size为1的数组输入,比如'[{}]'
#1189), 不过看起来不是一个好的feature, 引入导致了更严重的问题。
不如简单点,取消这个 feature 。
PS: 测试了一下 Jackson 与 Gson , 都没有这个 feature。
bug来自MapDeserializer
里面解析JSONArray的时候没限定类型,导致有下面结构的对象可以任意的被反序列化出来
{
"key":[
{
"anything":"anything",
}
]
}
限定类型之后问题就解决了.