JSON、GSON

  • Post author:
  • Post category:其他





什么是JSON



JSON(JavaScript Object Notation)


是一种与开发语言无关的、轻量级的

数据格式

;重点记住,它是一种数据格式 ;




特点

非常易于人的阅读和编写,同时也很容易被程序解析 ;




JSON的数据结构 – Object

使用花括号

{}

括起来的键值对结构,其中

key

必须是

String

类型,

value




任何



基本类型



数据结构

其中键值对内部使用冒号

:

连接, 键值对之间使用逗号

,

连接 ;




JSON的数据结构 – Array

使用中括号

[]

括起来,元素之间使用逗号

,

分隔 ;

元素也是可以为


任何


类型 ;




JSON的数据结构 – 基本类型

JSON 的基本类型有


5


种:


  • string

    代表字符串 ,字符串需要用双引号

    " "

    括起来 ;

  • number

    数值类型,

    JSON

    中只有一个

    number

    类型,是没有

    int float double

    这些类型的 ;

  • true/false

    布尔类型

  • null


    JSON

    中也定义了一个代表





    的关键字 ;

可以看见

JSON

好多的格式,都不支持,比如


日期


类型,这也是

JSON

的一个缺点,下面介绍的

GSON

弥补了这一缺点 ;




构建 JSON 数据

  1. 使用


    JSONObject


    对象构建

    JSON

    数据

    	@Test
        public void object2Json(){
    
    //        定义一个 null 对象 ;
            Object NULL = null ;
    
    //        利用 jsonObject 对象,构建 JSON
            JSONObject jsonObject = new JSONObject() ;
            jsonObject.put("name","yaz") ;
            jsonObject.put("sex","男") ;
    //        日期类型,用字符串,JSON 里面没有日期类型
            jsonObject.put("birthday","1997-01-22") ;
    //        插入数字的时候,java的数值类型,最后都会被转为 JSON 的number 类型
            jsonObject.put("salary",5000.00) ;
            jsonObject.put("age",22) ;
            jsonObject.put("hasHouse",false) ;
    //        直接传入 null ,编译不通过,因为 put 重载了 Collection 和 map 集合 ;
    //        直接传入 null ,就不知道具体调用哪一个了
    //        定义一个 null 对象,绕过编译 ;
    //        值为 null 的属性,不会被传入到 JSON 中 ;
            jsonObject.put("hasDream",NULL) ;
            jsonObject.put("habit",new String[]{"LOL","打乒乓球","java-IT"}) ;
    
            System.out.println(jsonObject.toString());
        }
    

    生成的


    JSON


    字符串 :

    {
      "birthday": "1997-01-22",
      "sex": "男",
      "habit": [
        "LOL",
        "打乒乓球",
        "java-IT"
      ],
      "hasHouse": false,
      "age": 22,
      "name": "yaz",
      "salary": 5000
    }
    
  2. 使用


    Map


    对象构建

    JSON

    数据

    	@Test
        public void map2Json(){
            Map<String,Object> map = new HashMap<>();
            map.put("name","yaz") ;
            map.put("age",22) ;
            map.put("birthday","97-01-22") ;
            map.put("salary",5000.1) ;
            map.put("habit",new String[]{"LOL","Music","sleep"}) ;
            map.put("hasHouse",false) ;
            map.put("car",null) ;
    
    //        还是需要 JSONObject ,将 map 传入
            JSONObject jsonObject = new JSONObject(map) ;
    
            System.out.println(jsonObject);
        }
    

    生成的


    JSON


    字符串 :

    {
      "birthday": "97-01-22",
      "habit": [
        "LOL",
        "Music",
        "sleep"
      ],
      "hasHouse": false,
      "name": "yaz",
      "age": 22,
      "salary": 5000.1
    }
    
  3. 使用


    Javabean


    对象构建

    JSON

    数据

    (推荐使用)

       @Test
        public void Javabean2Json(){
            Customer customer = new Customer() ;
            customer.setAge(20);
            customer.setBirtyday("97-02-28");
            customer.setCarName(null);
            customer.setHabit(new String[]{"lol","java-IT"});
            customer.setSalary(5000.1);
            customer.setHasHouse(false);
    
            JSONObject jsonObject = new JSONObject(customer);
            System.out.println(jsonObject);
        }
    

    生成的

    JSON

    字符串 :

    {
      "birtyday": "97-02-28",
      "habit": [
        "lol",
        "java-IT"
      ],
      "hasHouse": false,
      "age": 20,
      "salary": 5000.1
    }
    

总结:

  1. 生成

    JSON

    串,都需要

    JSONObject

    对象 ,可以往里面一个一个属性的

    put

    ,也可以直接传给它一个

    map

    ,或者一个

    Javabean

    对象;
  2. 属性为


    null


    的属性,是不会为添加到

    JSON

    串中的 ;



解析 JSON 数据

  1. 从文件中读取

    JSON

  2. 解析数组

    这里有个缺点:

    JSON

    的工具类不能直接解析数组,需要使用

    JSONArray

    类辅助下 ;

  3. 判断

    null

    使用

    jsonObject.isNull("键")

    判断对应的属性,是否存在 ; ;

        @Test
        public void json2Object() throws IOException {
    //       获取 json 串所在的文件
            File file = new File(this.getClass().getClassLoader().getResource("jsonString.txt").getFile());
    //        使用 Apache 的 fileUtils工具,读取文本文件内容,转成字符串
            String json = FileUtils.readFileToString(file, "UTF-8");
    //        还是使用 JSONObject 对象
            JSONObject jsonObject = new JSONObject(json);
    
    //        读取 JSON 串的内容
    //        判断 是否有 name 属性,如果没有,则不读取;
            if (!jsonObject.isNull("name")) {
                System.out.println("name" + jsonObject.getString("name"));
            }
            System.out.println("age" + jsonObject.getInt("age"));
            System.out.println("salary" + jsonObject.getInt("salary"));
    //        但是读取数组,需要使用另外一个对象
            JSONArray jsonArray = jsonObject.getJSONArray("habit");
            for (int i = 0; i < jsonArray.length(); i++) {
    //            需要强转下
                String habit = (String) jsonArray.get(i);
                System.out.println("habit " + i + ":" + habit);
            }
    
        }
    

    这里有个坑:

    地址的写法,注意了,之前的写法,一直不好使,最后,直接建立一个资源文件,扔下面,然后访问到了


总结

:解析

JSON

串的时候,需要我们自己一个一个的去获取属性,对于数组属性,还需要强转,因为它不知道里面的具体类型 ;




GSON


Google

的一个开源项目,对


JSON


进行了增强,比如支持了日期类型;




构建 GSON

 @Test
    public void object2Gson() throws ParseException {
        CustomerWithDate customerWithDate = new CustomerWithDate();
        customerWithDate.setAge(22);
        customerWithDate.setName("yaz");
        customerWithDate.setBirtyday(new SimpleDateFormat("yyyy-mm-dd").parse("1997-1-22"));
        customerWithDate.setHabit(new String[]{"lol", "java"});
//        这个不会得到构建
        customerWithDate.setPassword("sasas");
//        美化输出样式,使用 GsonBuilder
        GsonBuilder gsonBuilder = new GsonBuilder();
//        进行个性化定制输出,也就是在构建的时候,对字段进行一些设定
        gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() {
            @Override
            public String translateName(Field field) {
                if ("name".equals(field.getName())){
                    return "YAZZZZ" ;
                }
                return field.getName();
            }
        }) ;

        gsonBuilder.setPrettyPrinting();
        Gson gson = gsonBuilder.create();
        System.out.println(gson.toJson(customerWithDate));
    }

使用

Javabean

或者

map

对象 都可以,

toJson

操作,参数是一个

object

类型 ;




解析 GSON

可以解析成自己的对象,而不是像

JSON

那样,解析成


JSONObject


对象 ;

   @Test
    public void gson2Object() throws IOException {
        //       获取 json 串所在的文件
//        地址的写法,注意了,之前的写法,一直不好使,直接建立一个资源文件,扔下面,然后访问到了
        File file = new File(this.getClass().getClassLoader().getResource("jsonString.txt").getFile());
//        使用 Apache 的 fileUtils工具,读取文本文件内容,转成字符串
        String json = FileUtils.readFileToString(file, "UTF-8");
//        创建一个 支持解析日期 的 gson
        Gson gson = new GsonBuilder().setDateFormat("yyyy-mm-dd").create() ;
        CustomerWithDate customerWithDate = gson.fromJson(json,CustomerWithDate.class);
        System.out.println(customerWithDate);
    }



对比 JSON 的强大之处

  1. 支持改变生成

    JSON

    的属性名(别名)

        /**
         * 设置别名,使用注解
         */
        @SerializedName("NAME")
        private String name;
    
  2. 美化输出

    //        美化输出样式,使用 GsonBuilder
            GsonBuilder gsonBuilder = new GsonBuilder() ;
            // 设置成漂亮的输出
            gsonBuilder.setPrettyPrinting();
    
  3. 在解析的过程中,进行个性化定制

    //        进行个性化定制输出,也就是在构建的时候,对字段进行一些设定
            gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() {
                @Override
                public String translateName(Field field) {
                    if ("name".equals(field.getName())){
                        return "YAZZZZ" ;
                    }
                    return field.getName();
                }
            }) ;
    
  4. 忽略掉某些

    Javabean

    的属性

    // 使用关键字 transient  在构建 JSON 的时候,会忽略掉该属性
      private transient String password;
    
  5. 支持解析日期

    设定日期解析格式 ;

    //        创建一个 支持解析日期 的 gson
            Gson gson = new GsonBuilder().setDateFormat("yyyy-mm-dd").create() ;
    
  6. 支持


    JSON




    Array


    数组到

    java

    集合类的无缝转换

    说的是,对于

    JSON



    Array

    数组,我们在 java 里面是可以直接用


    集合


    接收的,


    GSON


    会自动的转换 ;



版权声明:本文为youngyouth原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。