遭遇fastjson的一个坑

前端之家收集整理的这篇文章主要介绍了遭遇fastjson的一个坑前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近在开发过程中踩到到了fastjson的一个坑,写出来跟大家分享一下,同时也留个记录。
情况是这样子的,我们中间件是采用fastjson来进行序列化的,我们自己在代码中定义一个Response类用于封装两个系统之间交换的数据,代码简化版大致如下:

public@H_404_8@ class@H_404_8@ Response@H_404_8@<T@H_404_8@> {@H_404_8@

    private@H_404_8@ int@H_404_8@ status;//用于标志调用状态@H_404_8@

    private@H_404_8@ T data;//实际数据@H_404_8@

    public@H_404_8@ int@H_404_8@ getStatus@H_404_8@() {
        return@H_404_8@ status;
    }

    public@H_404_8@ void@H_404_8@ setStatus@H_404_8@(int@H_404_8@ status) {
        this@H_404_8@.status = status;
    }

    public@H_404_8@ T getData@H_404_8@() {
        return@H_404_8@ data;
    }

    public@H_404_8@ void@H_404_8@ setData@H_404_8@(T data) {
        this@H_404_8@.data = data;
    }

    public@H_404_8@ boolean@H_404_8@ isSuccess@H_404_8@() {
        return@H_404_8@ data != null@H_404_8@ ? true@H_404_8@ : false@H_404_8@;
    }

    public@H_404_8@ void@H_404_8@ setSuccess@H_404_8@(T data){
        this@H_404_8@.data = data;
        this@H_404_8@.status = SUCCESS;
        //do something success@H_404_8@
    }

    @Override@H_404_8@
    public@H_404_8@ String toString@H_404_8@() {
        return@H_404_8@ "Response{"@H_404_8@ +
                "status="@H_404_8@ + status +
                ",data="@H_404_8@ + data +
                '}'@H_404_8@;
    }
}

Response类中封装一个泛类型data成员为实际需要的数据,定义的datagetset方法,定义的一个isSuccess()方法来判定系统是否成功给client端用。定义了一个setSuccess()方法给server端用。

如下实例化一个Response对象:

Response<String@H_404_8@> response = new@H_404_8@ Response<>();
response.setData("test"@H_404_8@);
response.setStatus(0@H_404_8@);
String@H_404_8@ json = JSON@H_404_8@.toJSONString(response);//fastjson序列化@H_404_8@
System.out.println(json);//打印出序列化json@H_404_8@
response = JSON@H_404_8@.parSEObject(json,Response.class);//fastjson序列化反java对象@H_404_8@
System.out.println(response);//打印出反序列化java对象@H_404_8@

预计json序列化结果为:

{"data@H_404_8@":"test"@H_404_8@@H_404_8@,"status@H_404_8@":0@H_404_8@@H_404_8@}

而实际用“,输出的json确实如下:

{"data@H_404_8@":"test"@H_404_8@@H_404_8@,"status@H_404_8@":0@H_404_8@@H_404_8@,"success@H_404_8@":true@H_404_8@@H_404_8@}

发现了没,序列化的json中多了一个success,这跟设计的不太一样啊!!这可不是我要的结果….多了个对实际程序影响还没有那么大,更坑爹的还在后面的反序列化,输出结果如下:

Response@H_404_8@{status=0@H_404_8@,data@H_404_8@=true}@H_404_8@

而不是:

Response@H_404_8@{status=0@H_404_8@,data@H_404_8@="test"}@H_404_8@

data中的数据被篡改了,类型都不对了有木有…这将导致很严重的后果!

这主要是Response不是一个标准的POJO类,isSuccess()setSuccess()刚好被fastjson多解析为successgetset方法,然后setSuccess()在反序列化时把序列化结果中的success值覆盖掉了data,多个条件碰到了一起,造成了悲剧…
其实解决办法很简单,使用标准的POJO或者修改一下isSuccess()setSuccess()方法名即可。 因此建议大家在使用类似于fastjson这种工具进行序列化时要注意改问题,避免这种悲剧的重演。

猜你在找的Json相关文章