ZhouXiangの博客 后端工程师&机器学习爱好者

JSON简介

2019-04-15

JSON简介。

Json是什么

JSON起源于1999年的JS语言规范ECMA262的一个子集(即15.12章节描述了格式与解析),后来2003年作为一个数据格式ECMA404(很囧的序号有不有?)发布.2006年,作为rfc4627发布,这时规范增加到18页,去掉没用的部分,十页不到.

结构

  • 只有两种基本结构:对象内的键值对集合结构和数组,对象用{}表示、内部是”key”:”value”,数组用[]表示,不同值用逗号分开.
  • 基本数值有7个: false / null / true / object / array / number / string
  • 结构可以嵌套,进而可以用来表达复杂的数据,例如:
    {
     "Image": {
         "Width":  800,
         "Height": 600,
         "Title":  "View from 15th Floor",
         "Thumbnail": {
             "Url":    "http://www.example.com/image/481989943",
             "Height": 125,
             "Width":  "100"
         },
         "IDs": [116, 943, 234, 38793]
       }
    }
    

优点

  • 基于纯文本,阅读性好.
  • 规范简单,容易处理,开箱即用,特别是JS类的ECMA脚本里是内建支持的,可以直接作为对象使用.
  • 平台无关性,因为类型和结构都是平台无关的,而且好处理,容易实现不同语言的处理类库,可以作为多个不同异构系统之间的数据传输格式协议,特别是在HTTP/REST下的数据格式.

缺点

  • 性能一般,文本表示的数据一般来说比二进制大得多,在数据传输上和解析处理上都要更影响性能.
  • 缺乏schema,跟同是文本数据格式的XML比,在类型的严格性和丰富性上要差很多.

编码指南

  • 属性名和值都是用双引号,不要把注释写到对象里面,对象数据要简洁
  • 不要随意结构化分组对象,推荐是用扁平化方式,层次不要太复杂
  • 命名方式要有意义,比如单复数表示
  • 驼峰式命名,遵循Bean规范
  • 使用版本来控制变更冲突
  • 对于一些关键字,不要拿来做key
  • 如果一个属性是可选的或者包含空值或null值,考虑从JSON中去掉该属性,除非它的存在有很强的语义原因
  • 序列化枚举类型时,使用name而不是value
  • 日期要用标准格式处理
  • 设计好通用的分页参数
  • 设计好异常处理

详细参考:https://github.com/darcyliu/google-styleguide/blob/master/JSONStyleGuide.md

应用场景

  • 内部后台系统之间的数据传输,此种情况下基于HTTP的JSON格式其实没有优势.
  • 前后台之间的API调用,典型的是前端作为React/VUE/AngularJS/ExtJS等框架做的,前后端使用JSON交互.
  • 提供给第三方的开发接口API.

Jackson常用API

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zx</groupId>
    <artifactId>json</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>
    </dependencies>

</project>

Demo

public class User {

    public User() {

    }

    public User(String name, Integer age, Date date, String email) {
        this.name = name;
        this.age = age;
        this.birthday = date;
        this.email = email;
    }

    private String name;
    private Integer age;
    private Date birthday;
    private String email;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "com.zx.json.User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                ", email='" + email + '\'' +
                '}';
    }

}
package com.zx.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author :Alitria
 * @date :Created in 2019/1/16 17:37
 * @description:
 * @modified By:
 * @version: $
 */
public class JacksonDemo {

    /**
     * ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。
     * ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。
     * writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。
     * writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。
     * writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。
     * writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。
     */

    /*
        Java对象转Json字符串
     */
    public static void pojo2json() throws ParseException, JsonProcessingException {
        User user = new User();
        user.setName("zhangsan");
        user.setEmail("zhangsan@163.com");
        user.setAge(20);
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        user.setBirthday(dateformat.parse("1996-10-01"));
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(user);
        System.out.println(json);
    }
    /*
        Java-List转Json字符串
     */
    public static void pojoList2json() throws ParseException, JsonProcessingException {
        List<User> users = new ArrayList<User>();
        User user = new User();
        user.setName("zhangsan");
        user.setEmail("zhangsan@163.com");
        user.setAge(20);
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        user.setBirthday(dateformat.parse("1996-10-01"));
        users.add(user);
        ObjectMapper mapper = new ObjectMapper();
        String jsonlist = mapper.writeValueAsString(users);
        System.out.println(jsonlist);
    }
    /*
        Json字符串转Java对象
     */
    public static void json2pojo() throws Exception {
        String jsonInStr = "{\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}";
        ObjectMapper mapper = new ObjectMapper();
        User user = mapper.readValue(jsonInStr, User.class);
        System.out.println(user.getName());
        System.out.println(user.getEmail());
        System.out.println(user.getBirthday());
        System.out.println(user.getAge());
    }
    /*
        Json字符串数组转Java_List
     */
    public static void jsonArray2pojo() throws Exception {
        String jsonInStr = "[{\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}]";
        ObjectMapper mapper = new ObjectMapper();
        List<User> userList = mapper.readValue(jsonInStr, new TypeReference<List<User>>() {});
        for(User user: userList) {
            System.out.println(user.getName());
            System.out.println(user.getEmail());
            System.out.println(user.getBirthday());
            System.out.println(user.getAge());
        }
    }
    /*
        Json字符串转Map
     */
    public static void json2map() throws IOException {
        String jsonInStr = "{\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}";
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> map = mapper.readValue(jsonInStr, new TypeReference<HashMap<String, Object>>(){});
        for(Map.Entry<String, Object> entry: map.entrySet()) {
            System.out.println(entry.getKey()+"  "+entry.getValue());
        }
    }
    /*
        Json字符串转节点
     */
    public static void json2node() throws IOException {
        String jsonInStr = "{\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(jsonInStr);
        System.out.println(root.get("name").asText());
    }
    /*
        Json字符串转数组
     */
    public static void jsonArray2Array() throws IOException {
        String jsonInStr = "[" +
                "{\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}, " +
                "{\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}" +
                "]";
        ObjectMapper mapper = new ObjectMapper();
        User[] array = mapper.readValue(jsonInStr, new TypeReference<User[]>(){});
        for(int i=0; i<array.length; i++) {
            System.out.println(array[i].getAge());
            System.out.println(array[i].getBirthday());
            System.out.println(array[i].getEmail());
            System.out.println(array[i].getName());
        }
    }
    /*
        递归遍历Json字符串
     */
    public static void jsonLeaf(JsonNode node) {
        if(node.isValueNode()) {
            System.out.println(node.getNodeType()+"  "+node.toString());
            return;
        }
        if(node.isObject()) {
            Iterator<Map.Entry<String, JsonNode>> it = node.fields();
            while (it.hasNext()) {
                Map.Entry<String, JsonNode> entry = it.next();
                jsonLeaf(entry.getValue());
            }
        }
        if(node.isArray()) {
            Iterator<JsonNode> it = node.iterator();
            while (it.hasNext()) {
                jsonLeaf(it.next());
            }
        }
    }
    public static void completedJsonRead() throws IOException {
//        String jsonInStr = "[{\"id\":\"1\"}, {\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}]";
        String jsonInStr = "[{\"id\":\"1\"}, {\"ip\":{\"addr\":\"10.1.18.3\"}},{\"name\":\"zhangsan\",\"age\":20,\"birthday\":844099200000,\"email\":\"zhangsan@163.com\"}]";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode node = mapper.readTree(jsonInStr);
        jsonLeaf(node);
    }

    public static void main(String[] args) throws Exception, ParseException, IOException, ClassNotFoundException {
        completedJsonRead();
    }

}

FastJson常见Api

Pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>json</artifactId>
        <groupId>com.zx</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>fastjson</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.54</version>
        </dependency>
    </dependencies>
</project>

Demo

public class User {
    String username;
    String password;

    public User() {
    }
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }
}
public class UserGroup {
    private String name;
    private List<User> users = new ArrayList<User>();
    public UserGroup(){}
    public UserGroup(String name,List<User> users){
        this.name = name;
        this.users = users;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<User> getUsers() {
        return users;
    }
    public void setUsers(List<User> users) {
        this.users = users;
    }
    @Override
    public String toString() {
        return "UserGroup [name=" + name + ", users=" + users + "]";
    }
}
public class Demo {
    /*
        Java实例转Json字符串
     */
    public static void pojo2json() {
        User user = new User("zx", "950519");
        String json = JSON.toJSONString(user);
        System.out.println(json);
    }
    /*
        Java_List实例转Json字符串(数组)
     */
    public static void pojo_lits2json() {
        User user_1 = new User("zx", "950519");
        User user_2 = new User("lzx", "950608");
        List<User> userList = new ArrayList<User>();
        userList.add(user_1);
        userList.add(user_2);
        String json = JSON.toJSONString(userList);
        System.out.println(json);
    }
    /*
        Java组合实例转Json字符串(数组)
     */
    public static void completedPojo2json() {
        User user_1 = new User("zx", "950519");
        User user_2 = new User("lzx", "950608");
        List<User> userList = new ArrayList<User>();
        userList.add(user_1);
        userList.add(user_2);
        UserGroup userGroup = new UserGroup("1001", userList);
        String json = JSON.toJSONString(userList);
        System.out.println(json);
    }
    /*
        json字符串转Java实例
     */
    public static void json2pojo() {
        String strInJson = "{'password':'123456','username':'dmego'}";
//        User user = JSON.parseObject(strInJson, User.class);
        User user = JSON.parseObject(strInJson, new TypeReference<User>(){});
        System.out.println(user.toString());
    }
    /*
        json字符串转Java_List
     */
    public static void json2pojoList() {
        String strInJson = "[{'password':'123123','username':'zhangsan'},{'password':'321321','username':'lisi'}]";
        List<User> userList = JSONArray.parseObject(strInJson, new TypeReference<ArrayList<User>>() {});
        for(User user: userList) {
            System.out.println(user.getUsername()+"  "+user.getPassword());
        }
    }
    /*
        json字符串转复杂Java实例
     */
    public static void json2CompletedPojo() {
        String strInJson = "{'name':'userGroup_2008','users':[{'password':'123123','username':'zhangsan'},{'password':'321321','username':'lisi'}]}";
        UserGroup userGroup = JSON.parseObject(strInJson, new TypeReference<UserGroup>(){});
        System.out.println(userGroup.getName());
    }
    /*
        校验是否是合法Json字符串
     */
    public static boolean judgeIfValidJson(String strInJson) {
        try {
            JSONObject.parseObject(strInJson);
        } catch (JSONException ex) {
            try {
                JSONObject.parseArray(strInJson);
            } catch (JSONException ex1) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
          System.out.println(judgeIfValidJson("{ password':'123456','username':'dmego'}"));
    }
}

下一篇 秒杀系统实践

Comments

Content