关于JSON与JavaWeb
   软件工程   0 评论   1236 浏览

关于JSON与JavaWeb

   软件工程   0 评论   1236 浏览

来说说JSON

JSON是 (JavaScript Object Notation, JS 对象标记),它是一种数据交换格式。在JSON出现之前,大家一直用XML来传递数据。因为XML是一种纯文本格式,所以它适合在网络上交换数据。XML本身不算复杂,但是,加上DTD、XSD、XPath、XSLT等一大堆复杂的规范以后,任何正常的软件开发人员碰到XML都会感觉头大了。因此如何解决后端传各种各样的复杂数据格式来适应前端?这就是json诞生的原因。格式简单,易于读写,占用带宽小。

JSON 的语法规则十分简单,可称得上“优雅完美”,总结起来有:
数组(Array)用方括号(“[]”)表示。
对象(Object)用大括号(”{}”)表示。
名称/值对(name/value)组合成数组和对象。
名称(name)置于双引号中,值(value)有字符串、数值、布尔值、null、对象和数组。
并列的数据之间用逗号(“,”)分隔。

实例:
所以 {"name": "Michael"} 可以理解为是一个包含name为Michael的对象。
而[{"name": "Michael"},{"name": "Jerry"}]就表示包含两个对象的数组。
当然了,你也可以使用{"name":["Michael","Jerry"]}来简化上面一部,这是一个拥有一个name数组的对象。

SpringMVC的Json解析

主要有Jackson和国内阿里巴巴的Fastjson。

直接上Jackson的。
jar引入或者pom导入jackson-core、jackson-annotations、jackson-databind。我的版本都是2.9.5。
我的springMVC是5.0.2.RELEASE,随便创建个Controller类和Score实体类。

@RequestMapping("/json")
@ResponseBody
public Score toJson(){
    Score score = new Score();
    score.setCj("89");
    score.setJd(4.2f);
    return score;
}

前端访问/json得到结果:

{"scoreId":null,"xh":null,"kch":null,"cj":"89","jd":4.2,"xf":null}

使用Fastjson解析一言

Maven:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.67</version>
</dependency>

ANDROID :
implementation 'com.alibaba:fastjson:1.1.54.android'
public static void parseJsonWithJsonObject(Response response) {
    try {
        JSONObject jsonObject = JSONObject.parseObject(response.body().string());
        int id=jsonObject.getIntValue("id");
        String hitokoto = jsonObject.getString("hitokoto");
        System.out.println(id);
        System.out.println(hitokoto);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void sendRequestWithOkhttp(String address, okhttp3.Callback callback) {
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder().url(address).build();
    client.newCall(request).enqueue(callback);
}

HttpUtil.sendRequestWithOkhttp("https://v1.hitokoto.cn/", new okhttp3.Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        parseJsonWithJsonObject(response);
    }
});

解析json数组

JSONObject jsonObject = JSON.parseObject(res.toString());
JSONArray jsonArray = jsonObject.getJSONArray("words_result");
Iterator<Object> iterator = jsonArray.iterator();
StringBuilder stringBuilder = new StringBuilder();
while (iterator.hasNext()) {
    JSONObject object = (JSONObject) iterator.next();
    stringBuilder.append(object.get("words"));
}

为啥主流还是Jackson

既然阿里巴巴温少的Fastjson能够更快解析为啥用Jackson的开发者还是很多?
翻阅fastjson的源码,你会发现有很多写死的代码,比如:针对spring之类的框架的各种处理,都是用classload判断是否存在这种类名fastjson/SerializeConfig.java at master · alibaba/fastjson · GitHub;那么这是什么意思呢?意思就是如果你用spring的那种思想,自己写了个类似的功能,因为你这个项目里没有spring的那个类,那么用起来就有一堆bug;当然不仅限于这些。

其解析json主要是用的String类substring这个方法fastjson/JSONScanner.java at master · alibaba/fastjson · GitHub,所以解析起来非常“快”,因为申请内存次数很少。但是因为jdk1.7之前substring的实现并没有new一个新对象,在使用的时候,如果解析的json非常多,稍不注意就会出现内存泄漏(比如一个40K的json,你在对象里引用了里边的一个key,即使这个key只有2字节,也会导致这40K的json无法被垃圾回收器回收),这也是“快”带来的负面效果。而且这还不算,在jdk1.7以上版本对string的substring方法做了改写,改成了重新new一个string的方式,于是这个“快”的优势也不存在了。

总结

fastjson就是一个代码质量较差的国产类库,用很多投机取巧的的做法去实现所谓的“快”,而失去了原本应该兼容的java特性,对json标准遵循也不严格,自然很难流行。

json从发明到现在非常流行,并不是因为json快的原因(比json快且小巧的格式和类库一大把),而是因为json和web结合的时候更易于使用,对开发人员易于理解。很多人拿fastjson和jackson比,就像拿非智能机和iphone比待机时间,其功能性不一样,jackson的很多功能fastjson并没有实现,所以这种对比也不客观。fastjson之所以没在国际上流行起来,最主要的原因应该是开发者的思路全放到“快”上去了,而偏离了“标准”及功能性,质量也不够好,有点“舍本逐末”的味道。当然在目前的环境下,国产软件能踏实的心态做好开源的不多,fastjson团队能这么快的反馈并修正问题,这种精神还是值得称赞的。希望国内的技术从业者能更重视“技术的原始需求”。

本文由 RawChen 发表, 最后编辑时间为:2021-04-24 22:36
如果你觉得我的文章不错,不妨鼓励我继续写作。

发表评论
选择表情
Top