从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

    • 服务器软件

    • 环境管理和配置管理-科普篇
    • Servlet入门

      • 什么是Servlet
      • Servlet入门案例
      • Servlet生命周期
      • Servlet中的注解
      • Tomcat集成IDEA
      • Servlet体系结构
      • HTTP协议基础
      • 深入request和response对象
      • request对象基本使用
      • request其他功能
      • Servlet实现登录功能
      • HTTP协议基础-响应
      • Response对象基本使用
      • response对象之重定向
      • response输出字符到浏览器
      • response输出字节数据
      • 验证码案例
      • ServletContext
      • 文件下载案例
      • Cookie笔记
      • Cookie的更多细节
      • Cookie实践:记住上次访问时间
      • JSP入门
      • JSP的内置对象和案例
      • IDEA与JavaWeb的小技巧
      • Session笔记
      • 验证码案例
      • JSP深入学习
      • MVC开发模式
      • EL表达式和JSTL标签
      • JSTL标签库
      • 案例:列表的增删改查
      • Filter学习
      • Filter案例
      • Listener学习
      • Java中的Ajax
      • Java中的JSON
        • JSON的概念
        • JSON语法
        • 获取JSON里的数据
        • JSON解析器
        • Jackson
        • 案例:校验用户名是否存在
      • Servlet
    • JavaWeb
  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java并发

  • Java源码

  • JVM

  • 韩顺平

  • Java
  • Java
  • JavaWeb
  • Servlet入门
2023-04-17
目录

Java中的JSON

# 155.Java中的JSON

JSON,全称JavaScript Object Notation,译为JavaScript对象表示法,是一种非常常见的数据格式。

# JSON的概念

JSON现在多用于存储和交换文本信息的语法,比 XML 更小、更快,更易解析。

JSON表示数据的一个例子:

{
    "name":"张三",
    "age":23,
    "gender":"男"
}
1
2
3
4
5

‍

# JSON语法

基本规则如下:

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

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

    • 值的取值类型有如下集中:

      1. 数字(整数或浮点数)
      2. 字符串(在双引号中)
      3. 逻辑值(true 或 false)
      4. 数组(在方括号中) {"persons":[{},{}]}​
      5. 对象(在花括号中)​ {"address":{"province":"陕西"....}}​
      6. null
  • 数据由逗号分隔:多个键值对由逗号分隔

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

  • 方括号保存数组:[]

‍

我们来实践一下,创建一个新的HTML文件:01.JSON数据语法.html

// 1. 定义基本格式
  var person = {
    "name": "张三",
    "age" : 23,
    "gender": true
  }

  console.log(person);
1
2
3
4
5
6
7
8

可以看到有正常输出,这说明我们语法正确。

‍

第二种:

// 2. 垫套格式,例如JSON数据里有个数组
var personsData = {
	persons: [
	  {"name": "张三", "age" : 23, "gender": true},
	  {"name": "李四", "age" : 24, "gender": true},
	  {"name": "王五", "age" : 25, "gender": true}
	]
};
console.log(personsData)
1
2
3
4
5
6
7
8
9

‍

第三种:

// 3. 第三种嵌套格式:数组里定义多个JSON
  var personData3 = [
    {"name": "张三", "age" : 23, "gender": true},
    {"name": "李四", "age" : 24, "gender": true},
    {"name": "王五", "age" : 25, "gender": true}
  ]
  console.log(personData3)
1
2
3
4
5
6
7

‍

‍

‍

# 获取JSON里的数据

‍

JS中有如下方式获取JSON的数据:

  1. ​JSON对象.键名​
  2. ​JSON对象["键名"]​,通过中括号的方式获取,记得加引号
  3. ​数组对象[索引]​
  4. 遍历

‍

代码演示:

​JSON对象.键名​:

// 1. 定义基本格式
var person = {
    "name": "张三",
    "age" : 23,
    "gender": true
}
console.log(person.name)
console.log(person["name"])
1
2
3
4
5
6
7
8

‍

​JSON对象["键名"]​

 // 2。垫套格式,例如JSON数据里有个数组
          var personsData = {
            persons: [
              {"name": "张三", "age" : 23, "gender": true},
              {"name": "李四", "age" : 24, "gender": true},
              {"name": "王五", "age" : 25, "gender": true}
            ]
          };
          console.log(personsData.persons[2].name) //王五
1
2
3
4
5
6
7
8
9

‍

‍

​数组对象[索引]​

// 3. 第三种嵌套格式:数组里定义多个JSON
          var personsData3 = [
            {"name": "张三", "age" : 23, "gender": true},
            {"name": "李四", "age" : 24, "gender": true},
            {"name": "王五", "age" : 25, "gender": true}
          ]
          console.log(personsData3[1].name) // 李四
1
2
3
4
5
6
7

‍

‍

遍历

var person = {
            "name": "张三",
            "age" : 23,
            "gender": true
}

for( var key in person){
    console.log(key + " : " + person[key])
}
1
2
3
4
5
6
7
8
9

注意,不能用person.key的形式获取value,因为key是一个字符串,而 persion."name"​这样的写法是不对的。

‍

‍

var personsData3 = [
	{"name": "张三", "age" : 23, "gender": true},
	{"name": "李四", "age" : 24, "gender": true},
	{"name": "王五", "age" : 25, "gender": true}
]


for(var i = 0; i < personsData3.length; i++){
	var p = personsData3[i];
	for ( key in p){
	  console.log( key + &quot; : &quot; + p[key]);
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13

‍

# JSON解析器

浏览器和服务器之间经常是需要用JSON交换数据的,而在Java中,万物皆对象,我们经常需要将一个对象转为JSON格式的数据返回给浏览器,此时我们可以用一些第三方的工具类(也叫解析器)帮我们转换;

同时,浏览器发送给服务器JSON数据后,经常需要将JSON数据转为Java对象来操作。

常见的解析器:

  • Jsonlib,官方提供的
  • Gson,谷歌提供的
  • fastjson,阿里巴巴提供的
  • jackson,SpringMVC内置的解析器

‍

# Jackson

今天我们以jackson为例,使用步骤:

  1. 导入jackson的相关jar包
  2. 创建JavaBean
  3. 创建Jackson核心对象 ObjectMapper
  4. 调用ObjectMapper的相关方法进行转换

‍

# 导入依赖

jackson-annotations-2.2.3.jar
jackson-core-2.2.3.jar
jackson-databind-2.2.3.jar

‍

# 创建实体类

‍

我们创建一个person类,用来转换为JSON数据:

package com.peterjxl.domain;

public class Person {
    private String name;
    private int age;
    private String gender;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

‍

‍

# 使用Jackson来解析JSON

在Jackson中,核心对象是ObjectMapper​,我们转换对象为JSON就是用ObjectMapper​的方法来转换的。主要是如下方法:

  1. ​writeValueAsString(obj)​:将对象转为JSON字符串

  2. ​writeValue(参数1, obj)​ ,其中参数1是指定JSON字符串输出的位置,可以取下面的值:

    File:将obj对象转为JSON字符串,并保存到指定的文件中

    Writer:将obj对象转为JSON字符串,并将JSON数据填充到字符输出流中

    OutputStream:将obj对象转为JSON字符串,并将JSON数据填充到字节输出流中

‍

我们来演示下:

package com.peterjxl.domain;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

public class JacksonTest {

    @Test
    public void ObjectToJSON() throws Exception{
        Person p = new Person();
        p.setName("peter");
        p.setAge(18);
        p.setGender("男");

        // 2。创建jackon的核心对象 ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(p);
        System.out.println(json);
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

‍

运行结果:

{"name":"peter","age":18,"gender":"男"}
1

‍

‍

还可以写入到文件中:

mapper.writeValue(new File("Jackson.txt"), p);
mapper.writeValue(new FileWriter("Jackson2.txt"), p);
1
2

‍

文件内容:

{"name":"peter","age":18,"gender":"男"}
1

‍

‍

# Jackson的注解

Jackson提供了如下属性进行配置:

  1. @JsonIgnore:排除属性,使用了该注解的属性,转换为JSON数据时会被忽略
  2. @JsonFormat:配置属性值如何格式化,例如@JsonFormat(pattern = "yyyy-MM-dd")​

‍

我们给Person类加个日期类型的成员变量:

public class Person {
    private String name;
    private int age;
    private String gender;
    private Date birthday;
    // 这里省略getter和setter
}
1
2
3
4
5
6
7

‍

‍

来看看转换后的格式:

@Test
public void ObjectToJSON2() throws Exception{
    Person p = new Person();
    p.setName("peter");
    p.setAge(18);
    p.setGender("男");
    p.setBirthday(new Date());

    ObjectMapper mapper = new ObjectMapper();
    System.out.println(mapper.writeValueAsString(p));
}
1
2
3
4
5
6
7
8
9
10
11

‍

运行结果:日期类型被转换为毫秒值

{"name":"peter","age":18,"gender":"男","birthday":1681033967868}
1

‍

‍

‍

而如果我们加了一个注解:

public class Person {
    private String name;
    private int age;
    private String gender;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
}
1
2
3
4
5
6
7
8

‍

‍

再转换的结果:

{"name":"peter","age":18,"gender":"男","birthday":"2023-04-09"}
1

‍

‍

# Jackson转换集合

如果转换的是一个List集合,也能正常解析吗?可以的。List会被转换为数组格式,Map会被转换为对象格式。

‍

List转JSON示例:

@Test
    public void ObjectToJSON3() throws Exception{
        Person p = new Person("peter", 18,"男", new Date());
        Person p2 = new Person("peter2", 19,"男", new Date());
        Person p3 = new Person("peter3", 20,"男", new Date());
        List<Person> persons = new ArrayList<Person>();
        persons.add(p);
        persons.add(p2);
        persons.add(p3);

        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(persons));
    }
1
2
3
4
5
6
7
8
9
10
11
12
13

‍

运行结果:

[{"name":"peter","age":18,"gender":"男","birthday":"2023-04-09"},{"name":"peter2","age":19,"gender":"男","birthday":"2023-04-09"},{"name":"peter3","age":20,"gender":"男","birthday":"2023-04-09"}]
1

‍

Map转JSON示例:

 @Test
    public void ObjectToJSON4() throws Exception{
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("name", "张三");
        map.put("age", "23");
        map.put("gender", "男");

        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(map));
    }
1
2
3
4
5
6
7
8
9
10

‍

运行结果:

{"gender":"男","name":"张三","age":"23"}
1

‍

# JSON转Java

了解即可,用的较少。使用的是方法是readValue(json字符串数据,Class)​

‍

@Test
    public void JSONToObject() throws Exception{
        // 1. 初始化JSON字符串
        String json ="{\"gender\":\"男\",\"name\":\"张三\",\"age\":\"23\"}";
        // 2.创建ObjectMapper
        ObjectMapper mapper = new ObjectMapper();

        // 3.转为Java对象
        Person person = mapper.readValue(json, Person.class);
        System.out.println(person);
    }
1
2
3
4
5
6
7
8
9
10
11

‍

运行结果:

Person{name='张三', age=23, gender='男', birthday=null}
1

‍

# 案例:校验用户名是否存在

我们在日常冲浪的时候,有时候需要注册,在输入用户名的时候,有些网站会在输入完后校验是否存在同名的,存在则提示用户更换。这是怎么做的呢?Ajax,在用户输入完后,发送Ajax请求给服务器,服务器返回查询结果。例如百度:可以打开控制台观察结果

​​

‍

‍

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="../js/jquery-3.3.1.min.js"></script>
        <script>
            // 页面加载完成后
            $(function (){
                // 给username绑定blur事件
                $("#username").blur(function (){
                    var username = $(this).val()

                    // 期望服务器响应回的数据格式:
                    // { "userExsit": true, "msg" : "此用户名太受欢迎,请更换一个"}
                    // { "userExsit": false, "msg" : "用户名可用"}

                    $.get("/hello/findUserServlet", {username:username}, function (data){
                        // 判断userExsit的值
                        var span = $("#s_username")
                        if(data.userExist === true){
                            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" name="username" id="username" placeholder="请输入用户名"> <br/>
            <span id="s_username"> </span>
        </form>
    </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

‍

‍

为了简单起见,这里就不查询数据库了,而是直接判断:

package com.peterjxl.ajax;

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("/findUserServlet")
public class FindUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        Map<String , Object> map = new HashMap<>();
        // 1. 获取请求参数
        String username = req.getParameter("username");
        if("tom".equals(username)){
            map.put("userExsit", true);
            map.put("msg", "此用户名太受欢迎,请更换一个");
        }else{
            map.put("userExsit", false);
            map.put("msg", "用户名可用");
        }

        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(resp.getWriter(), map);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

‍

‍

重启Tomcat,访问http://localhost:8080/hello/JSON/04.register.html,并测试:

​

​

特别注意两个点:

  1. 在JS里,我们需要设置dataType为JSON,不然返回的是一个字符串,通过字符串去获取值是肯定不行的:data.userExist​,这也是常犯的一个错误。除非服务器设置了MIME类型:

    response.setContentType("application/json;charset=utf-8");
    
    1
  2. Servlet里注意设置编码为UTF-8

在GitHub上编辑此页 (opens new window)
上次更新: 2023/5/6 21:54:08
Java中的Ajax
Servlet

← Java中的Ajax Servlet→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式