首页 > 用json-lib,把json串转成java对象问题

用json-lib,把json串转成java对象问题

hi,问题是这样的,假设有一个java对象A,A里面有个String类型的字段data,data里面存放的是一个json串,现在我要将json串形式的A转化成一个java对象,这个过程中希望这个data字段还是以一个String的形式存在(即过程中不对data字段进行json到java的转换),有办法吗?
p.s. 如果问题描述不清,还请指出。


JSONObject
或者GSON,google实现的JSON形式
如有必要在贴上示例代码。


先理解一下 lz 的意思:

String str = "{ \"data\": \"{a:1,b:2}\" }";
JSONObject json = (JSONObject)JSONSerializer.toJSON(str);
System.out.println(json.getString("data"));

data 是一个 string ,其内容正好是一个 json 。输出为:

{"a":1,"b":2}

但期望的输出是

{a:1,b:2}

也就是说,toJSON 这个方法会自动把那些“可能是json”的字符串转换成 json object 。楼主希望 disable 掉这个 feature 。


如果我上面的理解没错的话。简单地说就是不可能。下面写一下分析过程:

我一开始认为这个库应该有一些 config 可以设置,查了一下 API 发现了 JsonConfig 这个类,但里面貌似没有相关的配置。于是我下了 json-lib 的源代码来看。

先从 JSONSerializer.toJSON() 看起,最后我发现 JSONObject.element(String key, Object value, JsonConfig jsonConfig) 这个方法就是有问题的。

证实一下这个结论,下面的代码,也会输出 {"a":1,"b":2}

json = new JSONObject();
json.element("data", "{a:1,b:2}");
System.out.println(json.getString("data"));

调用链:

JSONObject.element()
-> JSONObject.processValue()
-> JSONObject._processValue()
-> AbstractJSON._processValue()

最终定位到 AbstractJSON._processValue(Object value, JsonConfig jsonConfig) 这个方法

在这个方法里有一个 if( JSONUtils.isString( value ) ) 分支,它里面有一个 if( JSONUtils.mayBeJSON( str ) ) 分支。

看到这里代码的意图就明白了,mayBeJSON 会测试串是否“像”json,然后会递归调用 toJSON()

但似乎没有什么在 JsonConfig 我们能够控制的东西能够改变这个过程。

最后我找到了一个 word-around:将你的 json 改成:

{ "data": "'{a:1,b:2}'" }

也就是在双引号里面多加一层引号,会出来 {a:1,b:1}

但这里又有问题了,为什么 json-lib 会自己删除里面那层引号呢?上面的例子期望的结果应该是 '{a:1,b:1}' 才对吧?


所以 lz 应该可以看出 json-lib 的处理方式有很大问题。这里推荐 lz 使用 google 的 gson ,代码如下:

import org.junit.Assert;
import com.google.gson.Gson;

public class JsonTest {
    static class A {
        String data;
    }
    public static void main(String[] args) {
        final Gson gson = new Gson();
        final A a = gson.fromJson("{ \"data\": \"{a:1,b:2}\" }", A.class);
        Assert.assertEquals("{a:1,b:2}", a.data);
    }
}

通过反射,做到了类型安全的 json 解析,而且代码也很优雅。

P.S. lz 的问题描述确实是有些模糊的,清晰的问题描述参考我这个答案的开头部分。问题主要在于,作为一个没用过 json-lib 的人来看,会想,“data 既然是 String ,那么转成 java 之后肯定也是 String 罗”,谁会想到 json-lib 会自动把 string 变成 object 。

【热门文章】
【热门文章】