IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Ajax&Json -> 正文阅读

[JavaScript知识库]Ajax&Json

作者:recommend-item-box type_download clearfix

AJAX&JSON

资源:https://download.csdn.net/download/weixin_51297617/29227509

一. AJAX的概述

1.1 什么是ajax

在这里插入图片描述

? 异步JavaScript和XML (Asynchronous Javascript And XML)

1. 异步的访问方式
2. 使用到的技术:JavaScript和XML
   1).  JavaScript:ajax是js的异步请求技术
   2).  XML:用于封装服务器发送的大量的数据,因为XML无关的数据太多,而且解析比较麻烦。所以目前几乎不再使用了,使用JSON格式来代替。

<contactList>
   <contact> 
      <id>1</id>
      <name>潘金莲</name>
      <sex></sex>
      <address>烧饼店</address>
   </contact>
   <contact> 
      <id>2</id>
      <name>武大</name>
      <sex></sex>
      <address>烧饼连锁店</address>
    </contact>
</contactList>

1.2 同步和异步的区别

# 同步方式
	1. 浏览器与服务器是串行的操作,浏览器发起请求的时候,服务器在处理该请求的时候,浏览器只能等待。以前使用JSP开发的方式都是同步的方式。
	2. 缺点:执行效率低,用户体验差。	
#异步方式
	1. 浏览器与服务器是并行工作的
	2. 优点:执行效率高,用户体验更好。

在这里插入图片描述

? AJAX使用异步的提交方式,浏览器与服务器可以并行操作,即浏览器后台发送数据给服务器。用户在前台还是可以继续工作。用户感觉不到浏览器已经将数据发送给了服务器,并且服务器也已经返回了数据。

在这里插入图片描述

1.3 AJAX的应用场景

1.3.1 检查用户名是否已被注册

? 很多站点的注册页面都具备自动检测用户名是否存在的友好提示,该功能整体页面并没有刷新,但仍然可以异步与服务器端进行数据交换,查询用户的输入的用户名是否在数据库中已经存在。

在这里插入图片描述

1.3.2 内容自动补全

百度的搜索补全功能:

在这里插入图片描述

京东的搜索补全功能:

在这里插入图片描述

二. 原生ajax的访问流程[了解]

1.1 AJAX的执行流程

在这里插入图片描述

流程说明:

  1. 用户访问的时候,由JavaScript后台创建一个请求对象:XMLHttpRequest对象。
  2. 请求对象创建一个回调函数,回调函数用于处理服务器返回的响应
  3. 请求对象用于发送请求给服务器
  4. 服务器接收到浏览器发过来的请求,并且对数据进行处理。
  5. 将数据以XML的格式发送回浏览器,由XMLHttpRequest请求对象的回调函数接收数据
  6. 使用HTML和CSS更新网页最新结果

1.2 XMLHttpRequest对象

? 学习XMLHttpRequest对象有哪些事件,方法和属性

创建XMLHttpRequest对象说明
new XMLHttpRequest()构造方法直接创建对象
XMLHttpRequest对象的事件说明
on ready state change准备状态改变事件,这个事件是在以下情况激活:
1. 浏览器开始发送数据给服务器的时候
2. 浏览器数据发送完毕的时候
3. 服务器开始发送数据给浏览器的时候
4. 服务器数据发送完毕的时候
XMLHttpRequest对象的属性说明
readyState准备状态的值,当它等于4的时候,表示服务器数据接收完毕
status服务器的状态码。等于200的时候,服务器正确响应
responseText接收服务器返回的字符串数据
XMLHttpRequest对象的方法说明
open(“GET”,“URL”,true)打开服务器的连接
1. GET或POST表示请求的方式
2. URL访问服务器的地址
3. true/false 表示异步,false表示同步。
同步是指要等待服务器响应回来以后,才继续向后执行。
send()发送请求,如果是GET方法send()不需要参数。
如果是POST,send()需要传递浏览器端的数据

1.3 案例:使用原生的AJAX

package com.itheima01.ajax;

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;

@WebServlet("/AjaxServlet")
public class AjaxServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 接收请求
        String name = request.getParameter("name");
        String age = request.getParameter("age");
        System.out.println(name + "," + age);
        //2. 处理业务
//        int i = 1/0;
        //3. 响应数据
//        response.setHeader("content-type","text/html;charset=utf-8");
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("hello");
    }

}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <input type="button" value="js原生的ajax(get)请求" onclick="method01()"> <br>
    <input type="button" value="js原生的ajax(post)请求" onclick="method02()"> <br>
</body>
<script>

    function method01() {
        //1. 创建 ajax引擎 对象
        var xhr = new XMLHttpRequest();

        /*
            2. 设置监听(当准备状态改变的时候触发)
                1). 监听ajax请求状态改变
                2). 状态(readyState): 0~4 五种状态
                3). 0~1, 1~2 , 2~3, 3~4 有4次状态改变,所以这个函数会执行4次
                4). 重要: 最后一次,状态为4的时候: 此时响应了
         */
        xhr.onreadystatechange = function (ev) {
            console.log('xx') // 会被打印4次
            if(xhr.readyState == 4){
                if(xhr.status == 200){
                    //响应成功了!!!TODO
                        //获得字符串形式的响应数据。
                    alert(xhr.responseText)
                    // console.log(xhr.responseText)
                    // document.write(xhr.responseText)
                }else{
                    alert("响应失败")
                }
            }
        }
        /*
            3. 设置请求数据
                open(method,url,async)
                    method:请求的类型;GET 或 POST
                    url:文件在服务器上的位置
                    async:true(异步)或 false(同步)
         */
        let param = "name=zs&age=18"
        let url = "AjaxServlet?" + param
        xhr.open("get",url,true)

        /*
            4. 发送请求
                send(string)
                    string:仅用于 POST 请求

          */
        xhr.send();
    }
</script>
<script>
    function method02() {

        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function (ev) {
            console.log('xx') // 会被打印4次
            if(xhr.readyState == 4){
                if(xhr.status == 200){
                    alert(xhr.responseText)
                }else{
                    alert("响应失败")
                }
            }
        }
        /*
            3. 设置请求数据
                open(method,url,async)
                    method:请求的类型;GET 或 POST
                    url:文件在服务器上的位置
                    async:true(异步)或 false(同步)
         */
        let url = "AjaxServlet"
        xhr.open("post",url,true)

        /*
            4. 发送请求
                send(string)
                    string:仅用于 POST 请求

          */
        let param = "name=ls&age=19"
            //设置请求头, 影响请求体
        xhr.setRequestHeader("content-type","application/x-www-form-urlencoded")
        xhr.send(param);
    }
</script>
<!--<form action="" enctype="application/x-www-form-urlencoded"></form>-->
</html>

三. Ajax异步请求 axios (重要!)

3.1 axios介绍

  • 原生ajax请求的代码编写太过繁琐,我们可以使用axios这个库来简化操作!

    在后续学习的Vue(前端框架)中发送异步请求,使用的就是axios.

    需要注意的是axios不是vue的插件,它可以独立使用.

    axios(https://www.kancloud.cn/yunye/axios/234845)

  • 使用步骤
    1.引入axios核心js文件。
    2.调用axios对象的方法来发起异步请求。
    3.调用axios对象的方法来处理响应的数据。

  • axios常用方法

    在这里插入图片描述

    #备注: then函数的参数response是一个json对象,我们重点只需要了解response.data即可
    {
        // `data` 由服务器提供的响应 (重要!)
        data: {},
    
        // `status` 来自服务器响应的 HTTP 状态码
        status: 200,
    
        // `statusText` 来自服务器响应的 HTTP 状态信息
        statusText: 'OK',
    
        // `headers` 服务器响应的头
        headers: {},
    
        // `config` 是为请求提供的配置信息
        config: {}
    }
                            
    
  • 代码实现

    • html代码
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
            <input type="button" value="axios的get异步请求" onclick="method01()"> <br>
            <input type="button" value="axios的post异步请求" onclick="method02()"> <br>
    </body>
    <!--
        使用axios的步骤
            1. 放入 webapp/js/axios.js 文件
            2. 在当前html中声明使用axios.js 文件
    -->
    <script src="js/axios-0.18.0.js"></script>
    <script>
        function method01() {
            /*
            *  # axios的api介绍
            *  1. get(url)
            *       url : 请求地址(要包含请求参数)
            *  2. then(fn)
            *       fn(response) : 响应成功的回调函数
            *       response.data : 响应体数据
            *
            *  3. catch(fn)
            *       fn(error) : 响应失败的的回调函数
            *       error : 错误信息
            *
            *  4. finally(fn)
            *       fn : 响应结束的回调函数(无论响应成功与否,都会执行)
            * */
            let param = "name=zs&age=18"
            let url = "AjaxServlet?" + param
    
            let t = function(response){
                console.log(response)
                console.log(response.data) // 响应体数据
            }
            let c = function(error){
                console.log(error)
            }
            let f = function(){
                console.log("hehe")
            }
            // axios.get(url).then().catch().finally()
            // axios.get(url).then(t)
            // axios.get(url).then(t).catch(c)
            axios.get(url).then(t).catch(c).finally(f)
    
        }
    </script>
    
    <script>
        function method02() {
            /*
            *  1. post(url,param)
            *       url : 请求地址(不能包含请求参数)
            *       param : 请求参数(走请求体)
            *
            *  2. 箭头函数 (相当于java中的lambda表达式)
            *       es6的新语法 !!!
            *
            *       //普通函数
            *       function(response){
    
                        console.log(response.data) // 响应体数据
                    }
                    //箭头函数
                    response => {
                        console.log(response.data)
                    }
    
            * */
            let param = "name=ww&age=20"
            let url = "AjaxServlet"
    
            let t = function(response){
                console.log(response)
                console.log(response.data) // 响应体数据
            }
            let c = function(error){
                console.log(error)
            }
            let f = function(){
                console.log("hehe")
            }
            // axios.post(url,param).then().catch().finally()
    
           /* axios.post(url,param).then(function(response){
                console.log(response.data) // 响应体数据
            })*/
    
           /* axios.post(url,param).then(response => {
                console.log(response.data)
            })*/
    
            axios.post(url,param).then(response => {
                console.log(response.data)
            }).catch(error => {
                console.log(error);
            }).finally(()=>{
                console.log("xixi");
            })
    
    
        }
    </script>
    </html>
    
    • java代码
    package com.itheima01.ajax;
    
    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;
    
    @WebServlet("/AjaxServlet")
    public class AjaxServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1. 接收请求
            String name = request.getParameter("name");
            String age = request.getParameter("age");
            System.out.println(name + "," + age);
            //2. 处理业务
    //        int i = 1/0;
            //3. 响应数据
    //        response.setHeader("content-type","text/html;charset=utf-8");
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().print("hello");
        }
    
    }
    

3.2 检查用户名是否已被注册

#需求: 
	   a. 有一个注册的表单, 有注册用户名和密码,一个提交按钮
	   b. 用户名输完之后,检测这个用户名是否可用
	   c. 就算服务器没有立即响应, 用户还能继续在表单上操作 -> 异步
#分析:
	1. 用户名输入框注册一个失去焦点事件(onblur)
	2. 向服务器发送 异步 请求
	3. 服务器响应之后, 提示信息 局部更新到页面上
	   
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <form action="">
            <input type="text" name="username" placeholder="请输入用户名" id="username">
                <span id="usernameSpan"></span>
            <br>
            <input type="password" name="password" placeholder="请输入密码"> <br>
            <button>提交</button>
        </form>
</body>
<script src="js/axios-0.18.0.js"></script>
<script>
    /*
    *   需求: 查看此用户名是否已注册
    *   分析:
    *       1. 前提: 注册的用户存到数据库中了
    *       2. 判断: 数据库中是否有这个用户名
    *           1). 如果有, 提示已被注册不可用
    *           2). 如果没有, 提示可用
    *       3. sql : select * from user where name = ?;
    *
    *   前端: 发起请求
    *       事件: onblur
    *       1). 请求的类型: 异步 (不跳转而且只要页面局部更新)
    *       2). axios
    *           a. 请求地址
    *           b .请求参数
    *
    *   后端: 接收请求,业务处理,响应数据
    *       1). 获取请求参数
    *       2). 查询数据库
    *       3). 根据结果响应
    *
    *   前端: 接收响应, 显示数据
    *
    * */
    var usernameInput = document.getElementById("username");
    usernameInput.onblur = function () {
        let url = "CheckServlet"
        // let param = `username=${usernameInput.value}`
        let param = `username=${this.value}`

        // console.log(param)
        axios.post(url,param).then(resp=>{
            // console.log(resp.data)
            debugger//前端断点,可以通过代码实现
            if(resp.data == true){
                document.getElementById("usernameSpan").innerText = "此用户名可用"
            }else{
                document.getElementById("usernameSpan").innerText = "此用户名已存在,不可用"
            }
        })
    }
</script>
</html>
package com.itheima01.ajax;

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;

@WebServlet("/CheckServlet")
public class CheckServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        1). 获取请求参数
        // post中文乱码
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");

        //2). 查询数据库 (伪数据)
        if("jack".equalsIgnoreCase(username)){
            //用户名已存在,不可用
            response.getWriter().print("false");
        }else{
            //用户名不存在,可用
            response.getWriter().print("true");
        }
    }

}

四. JSON

4.1 JSON概述

JavaScript对象表示形式(JavaScript Object Notation : js对象简谱)

json是一种js对象文本表示形式

json是目前 前后端数据交互的主要格式之一

* java对象表示形式
		User user = new User();
			user.setUsername("后羿");
			user.setAge(23);
			user.setSex("男");
			...
			
		Product product = new Product();
			product.setName("小米10");
			product.setDesc("1亿像素的手机小王子");
			
* javaScript对象表示形式
		let user ={"username":"后羿","age":23,"sex":"男"}
		let product = {"name":"小米10","desc":"1亿像素的手机小王子"}

json可以取代XML笨重的数据结构,和xml相比:更小、更快,更易解析

json、xml作用:作为数据的载体,在网络中传输

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Pj3Q9B9-1633616549498)(assets/1590628812135.png)]

4.2 JSON基础语法

#json的语法主要有两种:
        1. 对象 { }
        2. 数组 [ ]
        
1. 对象类型
		{name:value,name:value}
		
2. 数组类型
		[
            {name:value,name:value}, 
            {name:value,name:value},
            {name:value,name:value}
		]
		
3. 复杂对象
		{
            name:value,
            wives:[{name:value},{},{}],
            son:{name:value}
		}
#注意: 
	1. 其中name必须是string类型
	2. value必须是以下数据类型之一:
		字符串
		数字
		对象(JSON 对象)
		数组
		布尔
		Null
	3. JSON 中的字符串必须用双引号包围。(单引号不行!)	
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    /*
    *  # 回顾
    *       1. js对象
    *       2. js数组
    * */
   /*
    let speak = function () {
        console.log(this.name + "正在说话");
    }
    function show(){
        console.log(this.name + "正在标案");
    }
    */
    let jsObj = {
        name : '张三',
        age : 18,
        married : true,
        speak : function () {
            console.log(this.name + "正在说话");
        },
        show(){
            console.log(this.name + "正在表演");
        }

    }

    jsObj.speak()
    jsObj.show()

    let jsArray = [jsObj,jsObj]
    let jsArray2 = ["a",true]

</script>
<script>
    /*
    *  JSON: js对象的文本表示形式
    *  1. 对象 {}
    *  2. 数组 []
    *
    *  注意点:
    *   1. 其中name必须是string类型
        2. value必须是以下数据类型之一:
            字符串
            数字
            对象(JSON 对象)
            数组
            布尔
            Null
        3. JSON 中的字符串必须用双引号包围。(单引号不行!)
    * */

    //1. json对象
    let jsonObj = {
        "name" : "张三",
        "age" : 18,
        "married" : true
    }
    let jsonObj2 = {
        "name" : "李四",
        "age" : 19,
        "married" : false
    }

    console.log(jsonObj.name + "," + jsonObj.age+"," + jsonObj.married);

    //2. json数组
    let jsonArray = [jsonObj,jsonObj2]
    console.log(jsonArray[1].name); // 李四

    //3. json复杂
    let jsonComplex = {
        "name" : "韦小宝",
        "age" : 20,
        "wives" : [jsonObj,jsonObj2]
    }

    console.log(jsonComplex.wives[0].name)

</script>
</html>

五. Fastjson

5.1 fastjson引入

需求

? 在服务器端有如下User对象需要响应给浏览器.

? 为了方便浏览器解析, 这就要求服务端在响应之前,需要将转成符合Json格式的字符串.

package com.itheima02.json;

public class User {
    private String username;
    private String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
    //TODO: 自己采用字符串拼接的方式输出。
    public String toJson() {
        return "{\"username\":\""+username+"\",\"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;
    }
}

? 通过拼接字符串的形式,将java对象转换成json格式字符串无疑是非常麻烦的,在开发中我们一般使用转换工具来达到实现.

? 所谓的转换工具是通过java封装好的一些jar工具包,可以直接将java对象或集合转换成json格式的字符串。

常见的json转换工具

在这里插入图片描述

其实这些工具使用起来都差不多, 目前我们学习使用的是Fastjson

5.2 fastjson 常用 API

fastjson 作用:

  1. 将java对象(PO)转成json字符串
  2. 将json字符串 转成 java对象(VO)

常用API

fastjson API 入口类是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON类上的静态方法直接完成。

public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本 

public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本解析成指定类型JavaBean 
public static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本解析成JavaBean集合 


5.3 fastjson 使用实例

5.3.1 导包

  <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

5.3.2 实体类

package com.itheima02.json;

public class User implements Serializable{
    private String username;
    private String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", 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;
    }
}

package com.itheima02.json;

import java.util.ArrayList;
import java.util.List;

public class UserGroup implements Serializable{
    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;
    }

    @Override
    public String toString() {
        return "UserGroup{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

5.3.3 测试

package com.itheima.test;

import com.alibaba.fastjson.JSON;
import com.itheima02.json.User;
import com.itheima02.json.UserGroup;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class FastjsonTest {

    private User user; // 对应 json对象
    private List<User> userList; // 对应 json 数组
    private UserGroup userGroup; // 对应 json 复杂

    private String userJsonString; // json对象字符串 -> User
    private String userListJsonString; // json数组字符串 -> List<User>
    private String userGroupJsonString; // json复杂字符串 -> UserGroup


    @Before
    public void init() {
        user = new User("张三", "123");

        userList = new ArrayList<User>();
        userList.add(new User("刘备", "123"));
        userList.add(new User("关羽", "456"));
        userList.add(new User("张飞", "789"));

        userGroup = new UserGroup();
        userGroup = new UserGroup("userGroups", userList);

        userJsonString = "{'password':'123','username':'张三三'}";
        userListJsonString = "[{'password':'123','username':'刘备'},{'password':'456','username':'关羽'},{'password':'789','username':'张飞'}]";
        userGroupJsonString = "{'name':'userGroups','users':[{'password':'123','username':'刘备'},{'password':'456','username':'关羽'},{'password':'789','username':'张飞'}]}";
    }

    //1. Java对象 -> JSON字符串
    @Test
    public void method01(){
            //核心类: com.alibaba.fastjson.JSON
            //public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本

        String jsonObj = JSON.toJSONString(user);
        System.out.println(jsonObj);


        String jsonArray = JSON.toJSONString(userList);
        System.out.println(jsonArray);

        String jsonComplex = JSON.toJSONString(userGroup);
        System.out.println(jsonComplex);

    }

    // 2. JSON字符串 -> java对象
    @Test
    public void method02(){
        /*
        * public static final <T> T parseObject(String text, Class<T> clazz);
        *       // 把JSON文本解析成指定类型JavaBean
        public static final <T> List<T> parseArray(String text, Class<T> clazz);
                //把JSON文本解析成JavaBean集合
        * */
        User user = JSON.parseObject(userJsonString, User.class);
        System.out.println(user);

        List<User> users = JSON.parseArray(userListJsonString, User.class);
        System.out.println(users);

        UserGroup group = JSON.parseObject(userGroupJsonString, UserGroup.class);
        System.out.println(group);
    }
}

六. axios和Fastjson综合

6.1 请求参数和响应数据都是普通字符串

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <input type="button" value="请求参数,后端响应都是普通字符串" onclick="send1()"> <br>
        <input type="button" value="后端响应换成Json格式" onclick="send2()"> <br>
        <input type="button" value="请求参数也换成Json格式" onclick="send3()"> <br>
</body>
<script src="js/axios-0.18.0.js"></script>
<script>
    function send1() {
        let url = "Union01Servlet"
        let param = "username=zs&password=123"

        axios.post(url,param).then(resp=>{
            console.log(resp.data); // 响应体数据
        })
    }
</script>
</html>
package com.itheima03.union.pojo.po;

import java.io.Serializable;

/*
*   PO: persistent object 持久化对象
*       数据库查询结果封装的JavaBean
* */
public class Contact implements Serializable {
    private Integer id;
    private String name;
    private boolean married;

    public Contact() {
    }

    public Contact(Integer id, String name, boolean married) {
        this.id = id;
        this.name = name;
        this.married = married;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", married=" + married +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public boolean isMarried() {
        return married;
    }

    public void setMarried(boolean married) {
        this.married = married;
    }
}

package com.itheima03.union;

import com.itheima03.union.pojo.po.Contact;

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

@WebServlet("/Union01Servlet")
public class Union01Servlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 接收请求
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        System.out.println(username + "," + password);
        //2. 业务处理 (数据库: 伪数据)
        Contact zs = new Contact(1, "张三", true);
        Contact ls = new Contact(2, "李四", false);

        ArrayList<Contact> list = new ArrayList<>();
        list.add(zs);
        list.add(ls);
        //3. 响应数据

        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print(list.toString());
    }

}

6.2 响应数据改成json格式

响应结果的封装

package com.itheima03.union.pojo.entity;

import java.io.Serializable;
/*
*   entity: 实体类
*       程序员封装的JavaBean, 统一数据格式
*
*  Result : 响应结果格式
*       1. 成功的数据
*           1). 增删改
*           2). 查询
*       2. 失败的数据
* */
public class Result implements Serializable {
    private boolean flag;//执行结果,true为执行成功 false为执行失败
    private String message;//返回结果信息
    private Object result;//返回数据(如果是查询操作则设置,如果是增删改则不设置)

    public Result() {
    }
    //失败,或者成功的增删改
    public Result(boolean flag, String message){
        this.flag = flag;
        this.message = message;
    }
    //成功的查询
    public Result(boolean flag, String message, Object result) {
        this.flag = flag;
        this.message = message;
        this.result = result;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }
}

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <input type="button" value="请求参数,后端响应都是普通字符串" onclick="send1()"> <br>
        <input type="button" value="后端响应换成Json格式" onclick="send2()"> <br>
        <input type="button" value="请求参数也换成Json格式" onclick="send3()"> <br>
</body>
<script src="js/axios-0.18.0.js"></script>
<script>
    function send1() {
        let url = "Union01Servlet"
        let param = "username=zs&password=123"

        axios.post(url,param).then(resp=>{
            console.log(typeof resp.data); //string
            console.log(resp.data); // 响应体数据
        })
    }
</script>

<script>
    function send2() {
    //同域当中   localhost:8080     
        let url = "Union02Servlet"
        let param = "username=ls&password=456"

        axios.post(url,param).then(resp=>{
            // console.log(typeof resp.data); // object
            // console.log(resp.data); //  响应体数据
            if (resp.data.flag){
                //成功
                console.log(resp.data.message);
                alert(resp.data.result);
            }else{
                //失败
                console.log(resp.data.message);
            }

        })
    }
</script>
</html>
package com.itheima03.union;

import com.alibaba.fastjson.JSON;
import com.itheima03.union.pojo.entity.Result;
import com.itheima03.union.pojo.po.Contact;

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

@WebServlet("/Union02Servlet")
public class Union02Servlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //1. 接收请求
            request.setCharacterEncoding("utf-8");
            String username = request.getParameter("username");
            String password = request.getParameter("password");

            System.out.println(username + "," + password);
            //2. 业务处理 (数据库: 伪数据)
            Contact zs = new Contact(1, "张三", true);
            Contact ls = new Contact(2, "李四", false);

            ArrayList<Contact> list = new ArrayList<>();
            list.add(zs);
            list.add(ls);

//            int i = 1/0; // 模拟服务器异常

            //3. 响应数据 TODO(普通字符串 -> json格式的字符串)


            //ContentType响应头指定的是响应体的数据类型 (MIME)
//        response.setContentType("text/html;charset=utf-8");
            response.setContentType("application/json;charset=utf-8");

            //代码1: java对象 -> json ,然后用响应体输出
//        String json = JSON.toJSONString(list);
//        response.getWriter().print(json);

            //代码2: java对象 -> json ,然后用响应体输出
//            JSON.writeJSONString(response.getWriter(),list);

            //代码3: 考虑响应结果的的封装
            JSON.writeJSONString(response.getWriter(),new Result(true,"查询成功",list));

        } catch (Exception e) { // 修改Exception,用来捕获算术异常
            e.printStackTrace(); // 异常信息打印控制台给程序员自己看
            response.setContentType("application/json;charset=utf-8");

            JSON.writeJSONString(response.getWriter(),new Result(false,"查询失败,请检查你家庭网络"));
        }
    }

}

6.3 请求参数改成json格式

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <input type="button" value="请求参数,后端响应都是普通字符串" onclick="send1()"> <br>
        <input type="button" value="后端响应换成Json格式" onclick="send2()"> <br>
        <input type="button" value="请求参数也换成Json格式" onclick="send3()"> <br>
</body>
<script src="js/axios-0.18.0.js"></script>
<script>
    function send1() {
        let url = "Union01Servlet"
        let param = "username=zs&password=123"

        axios.post(url,param).then(resp=>{
            console.log(typeof resp.data); //string
            console.log(resp.data); // 响应体数据
        })
    }
</script>

<script>
    function send2() {
        let url = "Union02Servlet"
        let param = "username=ls&password=456"

        axios.post(url,param).then(resp=>{
            // console.log(typeof resp.data); // object
            // console.log(resp.data); //  响应体数据
            if (resp.data.flag){
                //成功
                console.log(resp.data.message);
                alert(resp.data.result);
            }else{
                //失败
                console.log(resp.data.message);
            }

        })
    }
</script>
<script>
    function send3() {
        let url = "Union03Servlet"
        // let param = "username=ww&password=789"
        //TODO: 请求参数 -> json格式
        let param = {"username" : "ww","password" : "789"}

        axios.post(url,param).then(resp=>{
            if (resp.data.flag){
                //成功
                console.log(resp.data.message);
                alert(resp.data.result);
            }else{
                //失败
                console.log(resp.data.message);
            }

        })
    }
</script>
</html>
package com.itheima03.union.pojo.vo;

import java.io.Serializable;
/*
*   Vo: value Object (表示层)
*       javaBean 封装来自前端请求的数据
* */
public class User implements Serializable {

    private String username;
    private String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public String toJson() {
        return "{\"username\":\""+username+"\",\"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;
    }
}

package com.itheima03.union;

import com.alibaba.fastjson.JSON;
import com.itheima02.json.User;
import com.itheima03.union.entity.Result;
import com.itheima03.union.pojo.po.Contact;

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

@WebServlet("/Union03Servlet")
public class Union03Servlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //1. 接收请求
            User user = JSON.parseObject(request.getInputStream(), User.class);

            System.out.println(user);

            //2. 业务处理 (数据库: 伪数据)
            Contact zs = new Contact(1, "张三", true);
            Contact ls = new Contact(2, "李四", false);

            ArrayList<Contact> list = new ArrayList<>();
            list.add(zs);
            list.add(ls);

//            int i = 1/0; // 模拟服务器异常

            //3. 响应数据 TODO(普通字符串 -> json格式的字符串)
            response.setContentType("application/json;charset=utf-8");
            JSON.writeJSONString(response.getWriter(),new Result(true,"查询成功",list));

        } catch (Exception e) {
            e.printStackTrace();
            response.setContentType("application/json;charset=utf-8");
            JSON.writeJSONString(response.getWriter(),new Result(false,"查询失败,请检查你家庭网络"));
        }
    }

}

6.4 抽取BaseController

package cn.itcast.base;

import cn.itcast.entity.Result;
import cn.itcast.pojo.User;
import com.alibaba.fastjson.JSON;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class BaseController {

    /**
     * 将json数据转化为 java对象
     */
    public static <T> T parseJson2Object(HttpServletRequest request, Class<T> tClazz) throws IOException {
        return JSON.parseObject(request.getInputStream(), tClazz);
    }

    /**
     * 将响应结果 输出给浏览器
     */
    public static void printResult(HttpServletResponse response, Result result) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        JSON.writeJSONString(response.getWriter(), result);
    }

}

七.综合案例

自动补全项目搭建

需求

在输入框输入关键字,下拉框中异步显示与该关键字相关的用户名称

分析

  1. 查询以输入的关键字开头的用户
  2. 文本框使用keyup事件,得到文本框中的值,去掉前后空格。如果文本框的内容为空则不提交给服务器。
  3. 查询成功的回调函数中如果返回的用户数大于0才进行div的拼接,拼接以后显示在div中。
  4. 否则要隐藏div。
  5. 给大div中的子div绑定鼠标点击事件,点击某个名字则将div的文本内容显示在文本框中,并隐藏div

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-42cxc11P-1633616549507)(assets/1565427178364.png)]

效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uioSWFGA-1633616549511)(assets/1553220989638.png)]

导入数据库脚本

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  `password` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO `user` VALUES (1, '张三', '123');
INSERT INTO `user` VALUES (2, '李四', '123');
INSERT INTO `user` VALUES (3, '王五', '123');
INSERT INTO `user` VALUES (4, '赵六', '123');
INSERT INTO `user` VALUES (5, '田七', '123');
INSERT INTO `user` VALUES (6, '孙八', '123');
INSERT INTO `user` VALUES (7, '张三丰', '123');
INSERT INTO `user` VALUES (8, '张无忌', '123');
INSERT INTO `user` VALUES (9, '李寻欢', '123');
INSERT INTO `user` VALUES (10, '王维', '123');
INSERT INTO `user` VALUES (11, '李白', '123');
INSERT INTO `user` VALUES (12, '杜甫', '123');
INSERT INTO `user` VALUES (13, '李贺', '123');
INSERT INTO `user` VALUES (14, '李逵', '123');
INSERT INTO `user` VALUES (15, '宋江', '123');
INSERT INTO `user` VALUES (16, '王英', '123');
INSERT INTO `user` VALUES (17, '鲁智深', '123');
INSERT INTO `user` VALUES (18, '武松', '123');
INSERT INTO `user` VALUES (19, '张薇', '123');
INSERT INTO `user` VALUES (20, '张浩', '123');
INSERT INTO `user` VALUES (21, '刘小轩', '123');
INSERT INTO `user` VALUES (22, '刘浩宇', '123');
INSERT INTO `user` VALUES (23, '刘六', '123');

编写实体类

package com.itheima.pojo.po;

import java.io.Serializable;

public class User implements Serializable {

    private Integer id;
    private String name;
    private String password;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>自动完成</title>
    <style type="text/css">
        .content {
            width: 400px;
            margin: 30px auto;
            text-align: center;
        }

        input[type='text'] {
            box-sizing: border-box;
            width: 280px;
            height: 30px;
            font-size: 14px;
            border: 1px solid #38f;
        }

        input[type='button'] {
            width: 100px;
            height: 30px;
            background: #38f;
            border: 0;
            color: #fff;
            font-size: 15px;
        }

        #show {
            box-sizing: border-box;
            position: relative;
            left: 7px;
            font-size: 14px;
            width: 280px;
            border: 1px solid dodgerblue;
            text-align: left;
            border-top: 0;
            /*一开始是隐藏不可见*/
            display: none;
            height: 100px;
        }

        #show div {
            padding: 4px;
            background-color: white;
        }

        #show div:hover {
            /*鼠标移上去背景变色*/
            background-color: #3388ff;
            color: white;
        }
    </style>
</head>
<body>
<div class="content">
    <img alt="传智播客" src="img/logo.png"><br/><br/>
    <input type="text" name="word" id="word" onkeyup="method01()">
    <input type="button" value="搜索一下">
    <div id="show"></div>
</div>
<script src="js/axios-0.18.0.js"></script>
<script type="text/javascript">
    /*
    * # 需求: 当用户在输入框每输完一个字,就应该有提示, 如果框中没字,就没有提示
    *  0. sql :
    *           select * from user where name like ?
    *               关键字%
    *  1. 前端
    *       1). 请求类型: 异步
    *       2). 技术选型: axios
    *       3). 事件:  onchange不好用
    *                  onkeyup 当键盘抬起的时候
    *       4). 请求地址: AutoServlet
    *       5. 请求参数:  文本框输入的关键字
    *
    *
    *  2. 后端
    *       1). 接收请求
    *       2). 业务处理: 查询数据库
    *       3). 响应给浏览器
    *
    *  3. 前端
    *       1). 获取响应
    *       2). 显示数据
    *
    *
    * */
    function method01() {

        let url = "AutoServlet"
        //获取文本框中输入的值
        var show = document.getElementById("show");
        var value = document.getElementById("word").value;
        // value = "" 表达式 是 false
        if(!value){
            show.style.display = "none" // 修改css样式: 隐藏
            return;
        }
        let param = "keyword=" + value
        axios.post(url,param).then(resp=>{
            // console.log(resp.data);
            if(resp.data.flag){
                //响应成功
                var content = ""
                for(let user of resp.data.result){
                    content += user.name + "<br>"
                }
                show.style.display = "block" // 修改css样式: 显示
                show.innerHTML = content
            }
        })
    }
</script>
</body>
</html>
package com.itheima.web;

import com.alibaba.fastjson.JSON;
import com.itheima.entity.Result;
import com.itheima.pojo.po.User;
import com.itheima.service.UserService;

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("/AutoServlet")
public class AutoServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 获取请求
        request.setCharacterEncoding("utf-8");
        String keyword = request.getParameter("keyword");

        //2. 业务处理
        UserService service = new UserService();
        List<User> list = service.findUserByKd(keyword);

        //3. 响应数据
        response.setContentType("application/json;charset=utf-8");
        JSON.writeJSONString(response.getWriter(),new Result(true,"查询成功",list));

    }

}
package com.itheima.service;

import com.itheima.dao.UserDao;
import com.itheima.pojo.po.User;
import com.itheima.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class UserService {

    public List<User> findUserByKd(String keyword) {
        SqlSession session = SqlSessionUtil.getSession();

        UserDao mapper = session.getMapper(UserDao.class);
        List<User> list = mapper.findUserByKd(keyword);
        session.close();
        return list;
    }
}

package com.itheima.dao;

import com.itheima.pojo.po.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserDao {
    @Select("select * from user where name like concat(#{keyword},'%')")
    List<User> findUserByKd(String keyword);
}

package com.itheima.entity;

import java.io.Serializable;

/*
*   entity: 实体类
*       程序员封装的JavaBean, 统一数据格式
*
*  Result : 响应结果格式
*       1. 成功的数据
*           1). 增删改
*           2). 查询
*       2. 失败的数据
* */
public class Result implements Serializable {
    private boolean flag;//执行结果,true为执行成功 false为执行失败
    private String message;//返回结果信息
    private Object result;//返回数据(如果是查询操作则设置,如果是增删改则不设置)

    public Result() {
    }
    //失败,或者成功的增删改
    public Result(boolean flag, String message){
        this.flag = flag;
        this.message = message;
    }
    //成功的查询
    public Result(boolean flag, String message, Object result) {
        this.flag = flag;
        this.message = message;
        this.result = result;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }
}

总结:
1.web项目,前端是tomcat,后端servelet,是同域状态。
2.如果前端使用tomcat,后端使用springboot,那就要解决跨域问题。
3.前端如果使用vue(import)项目,后端使用springboot,就需要路由解决跨域问题,但这个状态下vue需要install编译;如果使用vue(script),就不需要编译,直接当静态文件访问,也是需要解决跨域路由问题。
4.注意跨域问题,前后端分离的基本,前端一个url,后端url跨域。
5.前端一般两种方式发送数据给后端(并返回数据),一种就是全域名url(可以直接发送),一种就是省略三要素的相对域名(uri)(拼接三要素),这个就需要封装文件,一个就是配置文件,一个就是路由文件。
6.后端也是可以用配置实现跨域,但有很多弊端,所以不用,这是就衍生出前端的跨域解决方案,所以现在基本上都是前端解决跨域问题。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-08 11:42:45  更:2021-10-08 11:43:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:17:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码