[alibaba/fastjson]序列化一个含有Map<byte[],byte[]>成员变量的对象,反序列失败,报expect ':' at 80, actual '异常

2023-12-20 488 views
6
public class Test {
   public static void main(String[] args) {
        String str = "abcd";
        Pojo2 obj = new Pojo2();
        Map<byte[], byte[]> map = new HashMap();
        map.put(str.getBytes(), str.getBytes());
        obj.setValues(new Object[]{map});

        byte[] ser = JSON.toJSONBytes(obj, new SerializerFeature[]{SerializerFeature.WriteClassName});
        obj = JSON.parseObject(ser, Pojo2.class, new Feature[0]);
        System.out.println(obj.toString());
   }
   public static class Pojo2 implements Serializable {
        private Object[] values;

        public Object[] getValues() {
            return values;
        }
        public void setValues(Object[] values) {
            this.values = values;
        }
    }
}

就会出现异常:


Exception in thread "main" com.alibaba.fastjson.JSONException: expect ':' at 0, actual '
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:296)
    at com.alibaba.fastjson.parser.deserializer.MapDeserializer.deserialze(MapDeserializer.java:74)
    at com.alibaba.fastjson.parser.deserializer.MapDeserializer.deserialze(MapDeserializer.java:43)
    at com.alibaba.fastjson.parser.deserializer.ContextObjectDeserializer.deserialze(ContextObjectDeserializer.java:9)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:395)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1401)
    at com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer.deserialze(JavaObjectDeserializer.java:46)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseArray(DefaultJSONParser.java:775)
    at com.alibaba.fastjson.serializer.ObjectArrayCodec.deserialze(ObjectArrayCodec.java:183)
    at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_1_Pojo2.deserialze(Unknown Source)
    at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:296)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:688)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:395)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:460)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:414)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:406)
``

而去掉SerializerFeature.WriteClassName序列化特性,能成功,但是Pojo2对象中的values为JSONObject,并且key和value都是String字符串了

回答

3
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.Data;
import org.junit.Test;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class Issue3623 {
    private static final String str = "abcd";

    @Test
    public void test2() {
        Pojo2 obj = new Pojo2();
        Map<byte[], byte[]> map = new HashMap<byte[], byte[]>();
        map.put(str.getBytes(), str.getBytes());
        obj.setValues(new Object[]{map});
        byte[] bytes = JSON.toJSONBytes(obj);
        System.out.println(new String(bytes));
        byte[] ser = JSON.toJSONBytes(obj,SerializerFeature.WriteClassName);
        System.out.println(new String(ser));
        obj = JSON.parseObject(ser, Pojo2.class, new Feature[0]);
        // System.out.println(obj);
    }

    @Data
    public static class Pojo2 implements Serializable {
        private Object[] values;
    }
}

输出

{"values":[{"YWJjZA==":"YWJjZA=="}]}
{"@type":"com.alibaba.json.bvt.issue_3600.Issue3623$Pojo2","values":[{"@type":"java.util.HashMap",x'61626364':x'61626364'}]}
com.alibaba.fastjson.JSONException: expect ':' at 0, actual '

可见加上SerializerFeature.WriteClassNamevalue部分出现了异常.

PS: 但是{"values":[{"YWJjZA==":"YWJjZA=="}]}反序列化之后内容也不对吧.

4
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.Data;
import org.junit.Assert;
import org.junit.Test;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class Issue3623 {
    private static final String str = "abcd";

    @Test
    public void test3() {
        Map<byte[], byte[]> map = new HashMap<byte[], byte[]>();
        map.put(str.getBytes(), str.getBytes());
        byte[] noClassName = JSON.toJSONBytes(map);
        byte[] ClassName = JSON.toJSONBytes(map, SerializerFeature.WriteClassName);
        String strNoClassName = new String(noClassName);
        String strClassName = new String(ClassName);
        System.out.println(strNoClassName);
        System.out.println(strClassName);
        Map<byte[], byte[]> map1 = JSON.parseObject(strNoClassName, new TypeReference<Map<byte[], byte[]>>(byte[].class, byte[].class) {
        }); // this line can psss
        Map<byte[], byte[]> map2 = JSON.parseObject(strClassName, new TypeReference<Map<byte[], byte[]>>(byte[].class, byte[].class) {
        }); // also this line can pass
        Assert.assertNotNull(JSON.parseObject(noClassName,map.getClass())); // this line is true
        Assert.assertNotNull(JSON.parseObject(ClassName,map.getClass())); // this line throw exception, why??
    }
}

output is

{"YWJjZA==":"YWJjZA=="}
{"@type":"java.util.HashMap",x'61626364':x'61626364'}
com.alibaba.fastjson.JSONException: expect ':' at 0, actual '