【JSON是什么】&【JSON的基本使用】

初识JSON

json

1、JSON概述

  • 什么是JSON

    JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式,同时也是一种JavaScript对象表示法。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
    官网JSON
    个人总结JSON原本是JS对象的字符串表示法(狭义上的JSON),但现在的JSON一般是指JSON字符串,是一种用于前后端数据的交换的格式,示例如下:

    //JS对象表示法:
    var 变量名 = {name : "zhangsan" , age : 8};//键名name和age也可以用引号包裹
    //JS对象的字符串表示法(JSON对象):
    var 变量名 = {"name" : "zhangsan" , "age" : "8"};
    
    //JS对象转JSON字符串:
    var json = JSON.stringify({"name" : "zhangsan","age" : "8"});
    //转换后的结果:json = '{"name" : "zhangsan","age" : "8"}'
    //JSON字符串转JS对象:
    var obj = JSON.parse('{"name" : "zhangsan","age" : "8"}');
    
  • 使用JSON传输数据的优点

    • 语法简单,易于学习
    • 层次结构鲜明,可读性高
    • 易于机器解析和生成,能够有效地提升数据的传输效率

2、JSON的基础语法

Json以key:value的形式表示数据

语法示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>
    var json={
        "name":"zhangsan",
        "age":"12",
        "address":["北京","上海","广州"]
    }
    alert(json.address);
</script>
</body>
</html>

image-20220811213403908

https://sp1.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=

3、序列化和反序列化

  • 序列化:将Java对象数据转换成JSON字符串数据
  • 反序列化:将JSON字符串数据转换成Java对象数据

序列化和反序列化需要使用Fastjson这个神器,Fastjson是阿里巴巴提供的一个Java语言编写的高性能且功能完善的JSION库,是目前Java语言中最快的JSON库,可以快速实现JSON对象和Java对象的相互转换。

阿里巴巴是真的强,前面的Druid也是性能最好的数据库连接池之一

Fastjson提供了两个API用与JSON字符串和Java对象的相互转换

  • String JSON.toJSONString(Objec obj):将Java对象转成JSON字符串
  • Object JSON.parseObject(String json):将JSON字符串转成Java对象

示例

Fastjson依赖:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

Java代码:

package com.hhxy.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hhxy.pojo.User;

/**
 * 练习Java对象和JSON的转换
 */
public class FastJsonDemo {
    public static void main(String[] args) {
        //创建一个Java对象
        User user = new User("张三", 18, '男');

        //1、将Java对象转成JSON字符串
        String json = JSON.toJSONString(user);
        System.out.println(json);//{"age":18,"gender":"男","name":"张三"}

        //2、将JSON字符串转成Java对象
        JSONObject u1 = JSON.parseObject("{\"age\":18,\"gender\":\"男\",\"name\":\"张三\"}");
        System.out.println(u1);//不设置默认是转成JSON对象,{"gender":"男","name":"张三","age":18}
        User u2 = JSON.parseObject("{\"age\":18,\"gender\":\"男\",\"name\":\"张三\"}",User.class);
        System.out.println(u2);//User{name='张三', age=18, gender=男}(记得重写Object的toString方法)
    }
}

实战演练

使用AJAX和JSON实现数据查询和数据添加功能

前期准备:

创建Web项目
导入依赖
创建所需目录
编写配置文件
创建实体类
  • Step1:创建Web项目

  • Step2:导入依赖

    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.hhxy</groupId>
        <artifactId>day13_brand-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
        <properties>
            <maven.compiler.source>16</maven.compiler.source>
            <maven.compiler.target>16</maven.compiler.target>
        </properties>
        <dependencies>
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.27</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.5</version>
            </dependency>
            <!--servlet-->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <!--fastjson-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.68</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <!--tomcat7-->
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <port>8080</port>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    
  • Step3:创建所需目录

    项目目录结构如下:

    image-20220818173843060

  • Step4:编写配置文件

    编写MyBatis配置核心配置文件,以及Mapper代理的配置文件

    略……

正式开始:

编写Mapper接口方法
编写工具类
编写service
编写servlet
编写html
  • 编写service:
package com.hhxy.service;

import com.hhxy.mapper.BrandMapper;
import com.hhxy.pojo.Brand;
import com.hhxy.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

public class BrandService {
    SqlSessionFactory sqlSF = SqlSessionFactoryUtil.getSqlSF();

    /**
     * 查询表中所有数据的方法
     * @return
     */
    public List<Brand> selectAll(){
        //1、调用工具类获取SqlSessionFactory对象
        //2、获取SqlSession对象
        SqlSession sqlS = sqlSF.openSession();
        //3、获取Mapper接口对象
        BrandMapper mapper = sqlS.getMapper(BrandMapper.class);
        //4、执行SQL语句
        List<Brand> brands = mapper.selectAll();
        //5、释放资源
        sqlS.close();
        return brands;
    }

    public boolean add(Brand brand){
        //1、调用工具类获取SqlSessionFactory对象
        //2、获取SqlSession对象
        SqlSession sqlS = sqlSF.openSession();
        //3、获取Mapper接口对象
        BrandMapper mapper = sqlS.getMapper(BrandMapper.class);
        //4、执行SQL语句
        //排除非空数据,brand==null 结果为false,这里有待优化
        if(brand.getBrandName() == null || brand.getOrdered() == null || brand.getOrdered() == null ||
                brand.getDescription() == null || brand.getStatus() == null){
            return false;
        }
        mapper.add(brand);
        //添加数据需要提交事物,未设置自动提交事物,就需要手动提交事物!
        sqlS.commit();
        //5、释放资源
        sqlS.close();
        return true;
    }
}
  • 编写servlet:

SelectAllServlet:

package com.hhxy.web;

import com.alibaba.fastjson.JSON;
import com.hhxy.pojo.Brand;
import com.hhxy.service.BrandService;

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.List;

@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    private BrandService service =  new BrandService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取Service对象
        //2、调用Service方法,获取数据库中的数据
        List<Brand> brands = service.selectAll();
        //3、将对象转换成JSON字符串 , 方便传输到前端页面  (序列化)
        String jsonString = JSON.toJSONString(brands);
//        System.out.println(jsonString);//打印看一下,JSON字符串是数组形式的
        //4、响应数据,将JSON字符串传输到前端页面去
        //4.1 处理中文数据,防止乱码
//        response.setContentType("test/html;charset=utf-8");//这样子改的
        response.setContentType("text/json;charset=utf-8");
        //4.2 响应
        response.getWriter().write(jsonString);
    }
}

AddServlet:

package com.hhxy.web;

import com.alibaba.fastjson.JSON;
import com.hhxy.pojo.Brand;
import com.hhxy.service.BrandService;

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.BufferedReader;
import java.io.IOException;

@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    private BrandService service = new BrandService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取Service对象

        //2、接收请求数据
        //2.1 接收来自addBrand.html的JSON数据
//        String brandName = request.getParameter("brandName");
        /*
        System.out.println(brandName);//输出:null
        request对象无法直接获取JSON数据!原因是getParameter方法获取字符串是依靠&、=等特殊字符进行分辨的
        需要使用原始的获取参数的方式,注意post和get获取方式的差别
        */
        String params = null;//用于接收JSON字符串转
//        System.out.println(request.getMethod());
        //当请求方式是POST时
        if("GET".equals(request.getMethod())){
            //当请求方式是GET时
            System.out.println("Get方式");
            // (几乎很少会使用GET去传递JSON数据。说明:一般而言JSON用来是传比较复杂的数据,
            // 而GET只能携带少量数据,且不安全,所以只适合传递较为简短的数据)
        }else{
            System.out.println("Post方式");
            //当请求方式是POST时
            BufferedReader br = request.getReader();
            params = br.readLine();
        }
        //2.2 将JSON数据转换成Java对象 (反序列化)
        Brand brand = JSON.parseObject(params, Brand.class);
        System.out.println("打印来自前端的JSON数据:"+brand);
        //3、调用service对象的方法,将数据添加到数据库中
        boolean flag = service.add(brand);
        System.out.println("1");
        //4、发送一个响应成功的标志
        if (flag) {
            System.out.println("2");
            response.getWriter().write("success");
        }
    }
}

编写html

brand.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>展示所有数据的也买你</title>
    <!--引入axios.js库-->
    <script src="../js/axios-0.18.0.js"></script>
</head>
<body>
<a href="addBrand.html"><input type="button" value="新增"></a><br>
<hr>
<table id="brandTable" border="1" cellspacing="0" width="100%">
</table>
<script>
    //当页面加载完成后,发送AJAX请求
    window.onload = function () {
        //1、发送AJAX请求
        axios({
            method:"get",
            url:"http://localhost:8080/day13_brand-demo/selectAllServlet"
        }).then(function (resp) {
            //2、获取响应数据
            let brands = resp.data;
            //显示表头数据,表头不参与遍历
            let tableData =
                "<tr>\n" +
                "        <th>序号</th>\n" +
                "        <th>品牌名称</th>\n" +
                "        <th>企业名称</th>\n" +
                "        <th>排序</th>\n" +
                "        <th>品牌介绍</th>\n" +
                "        <th>状态</th>\n" +
                "        <th>操作</th>\n" +
                "    </tr>";
            //3、遍历JSON字符串数组,获取数组中每一个brand对象
            for (let i = 0; i < brands.length; i++) {
                let brand = brands[i];
                tableData += "\n"+
                    "<tr align=\"center\">\n" +
                    "        <td>"+(i+1)+"</td>\n" +
                    "        <td>"+brand.brandName+"</td>\n" +
                    "        <td>"+brand.companyName+"</td>\n" +
                    "        <td>"+brand.ordered+"</td>\n" +
                    "        <td>"+brand.description+"</td>\n" +
                    "        <td>"+brand.statusStr+"</td>\n" +
                    "        <td><a href=\"#\">修改</a> <a href=\"#\">删除</a></td>\n" +
                    "    </tr>";
            }
            //将数据在表格中显示
            document.querySelector("#brandTable").innerHTML = tableData;//切记别给tableData加引号
        });
    }
</script>
</body>
</html>

addBrand.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据添加页面</title>
    <!--引入axios库-->
    <script src="../js/axios-0.18.0.js"></script>
</head>
<body>
<h3>添加品牌</h3>
<form action="" method="post">
    品牌名称:<input id="brandName" name="brandName"><br>
    企业名称:<input id="companyName" name="companyName"><br>
    排序:<input id="ordered" name="ordered"><br>
    描述信息:<textarea rows="5" cols="20" id="description" name="description"></textarea><br>
    状态:
    <input type="radio" name="status" value="0">禁用
    <input type="radio" name="status" value="1">启用<br>

    <input type="button" id="btn"  value="提交">
</form>
</body>
<script>
    //给按钮绑定一个点击事件,一旦点击提交按钮就发送给AJAX请求,实现局部刷星
    document.querySelector("#btn").onclick = function () {
        //0、将表单数据转换成JSON字符串
        var formData = {
            brandName : "",
            companyName : "",
            ordered : "",
            description : "",
            status : "",
        }
        //获取数据
        let brandName =  document.querySelector("#brandName").value;
        let companyName =  document.querySelector("#companyName").value;
        let ordered =  document.querySelector("#ordered").value;
        let description =  document.querySelector("#description").value;
        let status =  document.getElementsByName("status");//重点、难点!
        //设置数据
        formData.brandName = brandName;
        formData.companyName = companyName;
        formData.ordered = ordered;
        formData.description = description;
        for (let i = 0; i < status.length; i++) {
            if(status[i].checked){
                //被选中,获对应的值
                formData.status = status[i].value;
            }
        }
        console.log(formData.status);//打印测试一下

        //1、发送AJAX请求
        axios({
            method:"post",
            url:"http://localhost:8080/day13_brand-demo/addServlet",
            data:{
                brandName:formData.brandName,
                companyName:formData.companyName,
                ordered:formData.ordered,
                description:formData.description,
                status:formData.status
            }
        }).then(function (resp) {
            //判断响应是否成功
            if("success" == resp.data){
                location.href = "http://localhost:8080/day13_brand-demo/html/brand.html";
            }else{
                alert("数据添加失败,数据添不能为空!")
            }
        });
    }

</script>
</html>

image-20220818175443122

image-20220818175434437

期间遇到的问题

  • 空数据也能添加,添加空数据再进行查询时直接报空指针异常(这个错误虽然很简单,但是也让我看来半天,后来还是看到提示空指针异常才想到的)

  • Get方式发送的JSON数据,不易获取

  • 还遇到一个见鬼的事情,我用的是Get提交方式,最终出来的结果是POST方式。结果发现要将浏览器的缓存清理一下

    image-20220819205425941

注意事项

  • JSON数据一般是用POST方式进行传递的
  • JSON数据的接收方式,对于POST方式而言,只能用原始字符流进行接收,不能使用getParatmer这类通用方法
  • 数据响应到前端一定要记得设置编码格式
  • 禁用、启用的获取方式是getStatusStr

剩下的目标就是进一步完善修改和删除功能

结语

使用JSON+AJAX相较于之前的JSP现在显得更加麻烦!但是这只是暂时的!!!JSP直接混合着一起写,完全没有像JS这样为了动态或与数据写那么多重复的代码,他和JSP的代码执行路线是类似的,都是通过前端发送数据给Servlet,Servlet调用Service的方法处理请求数据,然后将响应的数据再返还给前端,最大的区别就是就是数据的交互是局部刷新!还有就是使用JSP给我的感觉就是一个功能要多次转发数据,代码的执行路线显得较为复杂。而AJAX就显得逻辑思路更加清晰,就是代码写的多,针对这一点就需要进一步学习Vue了。

越学高级的技术就越简单,但是底层技术不可忽视!高层技术的更新迭代会很快,而底层可能十年过去还是那样。


下一篇:初识Vue

推荐阅读

  • JavaWeb三大组件