JSON -粗略学习


最近学习了 AJAX 技术, 由于 AJAX 技术广泛地采用 JSON 为数据传递的格式,所以又去粗略的学习了一下 JSON

1. 概念

1.1 引入

​ 英文全称为 JavaScript Object Notation (中文:JavaScript对象表示法)

​ JSON 是存储和交换文本信息的语法。类似于 XML。

​ JSON 比 XML 更小、更快,更易解析。

​ 在 Java 中,我们可以去创建对象来封装信息,比如张三,23岁。

class Test {
    public static void main(String[] args) {
		Person p = new Person();
		p.setName("张三");
		p.setAge(23);
		p.setGender("男");
    }
}

class Person {
    private String name;
    private int age;
    private String gender;
    
    public Person(String name, int age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    
    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge(){
        return this.age;
    }
    
   	public void setAge(int age){
        this.age = age;
    }
    
    public String getGender() {
        return this.gender;
    }
    
    public void setGender(String gender) {
        this.gender = gender;
    }
}

​ 这样我们就使用了 Java 对象封装了这些零散的数据。在以后需要使用这些数据的时候,直接调用该对象当做参数,直接传递这些数据。

​ 所以,JavaScript 中零散的数据怎么办呢?

​ 我们就拥有了JSON。

1.2 什么是JSON

  • JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
  • JSON 是轻量级的文本数据交换格式
  • JSON 独立于语言 *
  • JSON 具有自我描述性,更易理解
var p = {"name" : "张三", "age" : 23, "gender" : "男"};

​ 这种表示方法我们就成为 JSON。

JSON现在多用于存储和交换文本信息的语法,在网络中进行数据的传输

2. 语法

2.1 基本规则

  • 数据在名称 / 值对中:JSON数据是由键值对构成的

    • 使用引号(单双都行)引起来,也可以不使用。

    • 值的取值类型:

      1. 数字 (整数或者浮点数)

      2. 字符串(在双引号中)

      3. 逻辑值(true 或 false)

      4. 数组(在方括号中)

        {"person":[{},{}]}
        
      5. 对象(在花括号中)

        {"address":{"province":"江苏"....}}
        
      6. null - 少见不常用

  • 数据有逗号分隔:多个键值对由逗号分隔

  • 花括号保存对象:使用 { } 来定义 JSON 格式

  • 方括号保存数据: [ ]

2.2.1 使用的例子:
<script>
        // 1.定义基本格式
        var person = {"name": "张三", "age": 23, "gender": true};
        alert(person);

        // 2.嵌套格式 {} - > []
        var persons = {
            "persons": [
                {"name": "张三", "age": 23, "gender": true},
                {"name": "李四", "age": 24, "gender": false},
                {"name": "王五", "age": 25, "gender": true}
            ]
        };
        alert(persons)

        // 3. 嵌套格式 [] -> {}
        var ps = [
            {"name": "张三", "age": 23, "gender": true},
            {"name": "李四", "age": 24, "gender": false},
            {"name": "王五", "age": 25, "gender": true}
        ]
    </script>

2.2 获取数据

  1. json 对象.键名
  2. json 对象[“键名”]
  3. 数组对象[索引]
<script>
        // 1.定义基本格式
        var person = {"name": "张三", "age": 23, "gender": true};
        alert(person);

        // 获取 name 的值
        var name = person.name;
        var name2 = person["name"];
        alert(name);
        alert(name2);

        // 2.嵌套格式 {} - > []
        var persons = {
            "persons": [
                {"name": "张三", "age": 23, "gender": true},
                {"name": "李四", "age": 24, "gender": false},
                {"name": "王五", "age": 25, "gender": true}
            ]
        };
        alert(persons)
        var name2 =  persons.persons[2].name;
        alert(name2);
        // 3. 嵌套格式 [] -> {}
        var ps = [
            {"name": "张三", "age": 23, "gender": true},
            {"name": "李四", "age": 24, "gender": false},
            {"name": "王五", "age": 25, "gender": true}
        ]

        var name3 = ps[2].name;
        alert(name3);
    </script>

​ 对于 json 对象中的数据,除了使用上述的几种方法,当我们需要获取 json 数组中的对象的时候,我们可以使用for循环。

<script>
var persons = {
            "persons": [
                {"name": "张三", "age": 23, "gender": true},
                {"name": "李四", "age": 24, "gender": false},
                {"name": "王五", "age": 25, "gender": true}
            ]
        };
        var ps = [
            {"name": "张三", "age": 23, "gender": true},
            {"name": "李四", "age": 24, "gender": false},
            {"name": "王五", "age": 25, "gender": true}
        ];

        // 获取 person 对象中的所有的键和值
        for(var i=0; i<persons.persons.length; i++) {
            for(var key in persons.persons[i]) {

                document.write(key + ":" + persons.persons[i][key]);
                document.write("<br/>");

            }
        }

        // 获取 ps 对象中的所有值
        for(var i=0; i<ps.length; i++) {
            for(var key in ps[i]) {
                document.write(key + ":" + ps[i][key]);
                document.write("<br/>");
            }
        }
</script>

3. JSON 数据和 Java 对象的相互转换

​ 在我们将 JSON 和 Java 之间相互转化的时候(客户端和服务器端的数据交互),我们会使用 JSON 解析器。

​ 什么是解析器?解析器就是封装好的一些工具类。

​ 常见的解析器:Jsonlib,Gson,fastjosn,jackson

​ 这次我们使用的是 jackson,因为 jackson 是 spring 框架中自带的。

3.1 JSON 转化为 Java 对象 - 和 3.2 的步骤基本一样,不再赘述

  1. 使用步骤:

    1. 导入 jackson 的相关 jar 包
    2. 创建 jackson 和新对象 ObjectMapper
    3. 调用 ObjectMapper 的相关方法来进行转换
      • readValue(json字符串数组, Class)
  2. 实例代码:

    @Test
        public void test5() throws IOException {
            // 1. 初始化 JSON 字符串
            String json = "{\"name\":\"张三\",\"age\":23,\"gender\":\"男\"}";
            // 2. 创建 ObjectMapper 对象
            ObjectMapper mapper = new ObjectMapper();
            // 3. 转化为 Java 对象 Person 对象
            Person person = mapper.readValue(json, Person.class);
    
            System.out.println(person);
        }
    // Person{name='张三', age=23, gender='男'}
    

3.2 Java 转化为 JSON 对象

  1. 使用步骤:

    1. 导入 jackson 的相关 jar 包

    2. 创建 jackson 和新对象 ObjectMapper

    3. 调用 ObjectMapper 的相关方法来进行转换

      • 转换方法:

        writeValue(参数1, obj)

        • 参数1:
          • File : 将 obj 对象转化为 JSON 字符串,并保存到指定的文件中
          • Writer:将 obj 对象转换为 JSON 字符串,并 json 数据填充到字符输出流中
          • OutputStream:将 obj 对象转化为 json 字符串,并将数据填充到字节输出流中

        writeValueAsString(obj) : 将对象转为json字符串

      • 注解:

        1. @JsonIgnore:排除属性(在后续转换成 json 格式数据时,忽略有注释的属性,选择要注释的属性,可以将注释标注在需要注释的属性上)
        2. @JsonFormat:属性值格式化
  2. 示例代码:

    • 使用步骤的实例代码

      import cn.itcast.domain.Person;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import org.junit.Test;
      
      import java.io.File;
      import java.io.FileWriter;
      
      public class JacksonTest {
      
      
          // Java 对象转为 JSON 字符串
          @Test
          public void test1() throws Exception {
              // 1. 创建 Person 对象
              Person p = new Person();
              p.setAge(23);
              p.setName("张三");
              p.setGender("男");
      
              // 2. 创建 Jackson 的核心对象 ObjectMapper
              ObjectMapper mapper = new ObjectMapper();
              // 3. 转换
              String json = mapper.writeValueAsString(p);
              System.out.println(json); // {"name":"张三","age":23,"gender":"男"}
      
              // writeValue : 将数据写到 d 盘的 a.txt 文件中
              mapper.writeValue(new File("d://a.txt"), p);
              // writeValue : 将数据关联到 Writer 中
              mapper.writeValue(new FileWriter("d://b.txt"), p);
          }
      }
      
    • 使用注释的实例代码

      • @JsonIgnore
      import com.fasterxml.jackson.annotation.JsonIgnore;
      public class Person {
          @JsonIgnore // 忽略该属性
          private Date birthday;
      	// get and set 方法不给出
      }
      
      • @JsonFormat
      import com.fasterxml.jackson.annotation.JsonFormat;
      import java.util.Date;
      
      public class Person {
          @JsonFormat(pattern = "yyyy-MM-dd")
          private Date birthday;
      }
      
    • 复杂 Java 对象转换

      • List:数组。

        @Test
        public void test3() throws Exception{
                // 1. 创建 Person 对象
                Person p1 = new Person();
                p1.setAge(23);
                p1.setName("张三");
                p1.setGender("男");
                p1.setBirthday(new Date());
        
                Person p2 = new Person();
                p2.setAge(23);
                p2.setName("张三");
                p2.setGender("男");
                p2.setBirthday(new Date());
        
                Person p3 = new Person();
                p3.setAge(23);
                p3.setName("张三");
                p3.setGender("男");
                p3.setBirthday(new Date());
        
                // 创建 List 集合
                List<Person> ps =new ArrayList<>();
                ps.add(p1);
                ps.add(p2);
                ps.add(p3);
        
                ObjectMapper mapper = new ObjectMapper();
                System.out.println(mapper.writeValueAsString(ps));
        
            }
        
      • Map:对象的格式是一致的。

        @Test
            public void test4() throws Exception {
                Person p1 = new Person();
                p1.setAge(23);
                p1.setName("张三");
                p1.setGender("男");
                p1.setBirthday(new Date());
        
                Person p2 = new Person();
                p2.setAge(23);
                p2.setName("张三");
                p2.setGender("男");
                p2.setBirthday(new Date());
        
                Person p3 = new Person();
                p3.setAge(23);
                p3.setName("张三");
                p3.setGender("男");
                p3.setBirthday(new Date());
                // 创建 map 对象
                Map<String, Person> map = new HashMap<>();
                map.put("员工1: ", p1);
                map.put("员工2: ", p2);
                map.put("员工3: ", p3);
        
                ObjectMapper mapper = new ObjectMapper();
                System.out.println(mapper.writeValueAsString(map));
            }
        

4. 案例 - 校验用户名是否存在

在这里插入图片描述

以上为百度注册时的注册页面,并不是这次案例的最终结果

注意点:

  1. 服务器响应的数据,在客户端使用时,想要当做 json 数据格式使用
    • $.get(type) : 最后一个参数设置为 “json”
    • 在服务器端设置 MIME 类型。 tomcat 为 “application/json;charset=utf-8”

以下为这次试验的代码:

​ html 页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
    <script src="js/jquery-3.4.1.min.js"></script>
    <script>

        // 在页面加载完成后
        $(function () {
            // 给 username 绑定 blur 时间
            $("#username").blur(function () {
                // 获取 username 文本输入框的值
                var username = $(this).val();
                // 发送 ajax 请求
                // 期望服务器响应回的数据格式是:{"userExist" : true, "msg" : "用户名已存在"}
                //                         {"userExist" : false, "msg" : "用户名可用"}
                $.get("findUserServlet", {username: username}, function (data) {
                    // 判断 userExist 键的值是否为 true
                    var span = $("#s_username");
                    if (data.userExist) {
                        span.css("color", "red");
                        span.html(data.msg);
                    } else {
                        span.css("color", "green");
                        span.html(data.msg);
                    }
                }, "json");
            });
        });

    </script>
</head>
<body>

<form>

    <input type="text" id="username" name="username" placeholder="请输入用户名">
    <span id="s_username"></span>
    <br/>
    <input type="password" name="password" placeholder="请输入密码"><br/>
    <input type="submit" value="注册"><br/>

</form>

</body>
</html>

​ servlet 代码:

package cn.itcast.web.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet(name = "FindUserServlet", urlPatterns = "/findUserServlet")
public class FindUserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

        // 1. 获取用户名
        String username = request.getParameter("username");

        // 2. 调用 service 层判断用户是否存在
        // 期望服务器响应回的数据格式是:{"userExist" : true, "msg" : "用户名已存在"}
        //                         {"userExist" : false, "msg" : "用户名可用"}
        Map<String, Object> map = new HashMap<String, Object>();
        if ("tom".equals(username)) {
            // 存在
            map.put("userExist",true);
            map.put("msg", "用户名已存在");
        }else{
            // 不存在
            map.put("userExist",false);
            map.put("msg", "用户名可用");
        }

        // 将 map 转为 json
        ObjectMapper mapper = new ObjectMapper();
        // 并传递给服务器端
        response.getWriter().write(mapper.writeValueAsString(map));

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值