ajax与json

什么是ajax

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指⼀种创建交互式网页应用的网页开发技术。

通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

传统的网页(不使用Ajax)如果需要更新内容,必须重新加载整个网页页面。

缺点

todo 这个场景暂时无法还原,先不进行八股的背诵,先看看,等遇到该场景再说吧

ajax 只能实现局部刷新,无法执行整体的页面跳转并携带数据。

ajax就是为了实现局部刷新,但有些场景忘了这回事儿的话,就是个坑。

同步与异步

  • 异步请求
    可以进行局部请求,整个页面不会刷新,进行数据的交互。

    客户端请求到服务器,如果服务器没有响应,客户端可以自由活动。异步的效率更高

  • 同步请求
    请求时,整个页面会进行加载,地址栏一般也会发生变化。

    客户端请求到服务器,如果服务器没有响应,客户端只能等待,卡死

以下面的图片举例,

  • 如果是异步请求,在等待响应的时候,仍然可以操作输入框
  • 如果是同步请求,在等待响应的时候,不可以操作输入框
    在这里插入图片描述

使用场景

  1. 用户注册 校验用户名。
  2. 搜索框中的提示。

什么时候用同步

在时序性较强的要求下使用同步,比如说一个函数需要另一个函数返回的值,使用异步就有可能得不到该值。

例如提交订单、提交用户信息这种操作上。

ajax

Ajax 存在于浏览器端的技术。一种用户交互数据的方式。

AJAX出现的目的
在不刷新页面的前提下,也可以跟服务器进行通信,从而根据服务器响应的信息,再根据js代码完成动态内容变化。

ajax原理

  • A 异步的 asynchronous
  • J JavaScript
  • A AND
  • X XML — text json
    X 代表数据的格式,XML规范,但重量级(需要定义规范的标签),现在常用的是json数据格式

ajax引擎存在于浏览器端, 异步请求的核心就是ajax引擎。

js基于对象语言,js中就存在这么一个类型对象XMLHttpRequest----ajax引擎!

XMLHttpRequest就是异步请求的对象,发送ajax请求的时候需要访问XMLHttpRequest对象。

同步请求:例如在浏览器端录入username,通过浏览器把请求整个发送给服务器,服务器端再把响应回来的数据整个发送给浏览器端,页面需要重新加载一遍

ajax异步请求:每个浏览器上都有一个ajax引擎,ajax引擎帮你发送局部请求,ajax发送请求的时候不会影响页面中的其他操作,ajax发送数据到服务器,服务器处理后把数据响应到ajax引擎,ajax引擎其实在js中,js会在浏览器端完成动态的操作。

js中原生的异步请求操作(了解)

  1. 创建AJAX引擎对象 XMLHttpRequest。
  2. 完成回调函数,当服务器响应成功之后会自动调用的函数。
    用于监听ajax引擎对象的状态,主要监听响应成功的之后!!
  3. 确认请求路径与方式。
  4. 发送请求。
package com.lx.servlet.ajaxTest;

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("/ajaxTest")
public class AjaxTest extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.getWriter().write("hello ajax");
    }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>原生的js异步请求</title>
</head>
<body>
    <input type="button" value="发送异步请求" onclick="fun()">
    <div id="myDiv"></div>
</body>


    <script type="text/javascript">

        // 发送ajax异步请求
        function fun() {

            // 1. 创建ajax引擎对象
            var httpRequest = new XMLHttpRequest();

            // 2. 监听ajax请求对象 主要监听响应成功后的操作
            httpRequest.onreadystatechange = function () {

                // 如果请求对象的状态发生改变 就会触发该函数

                // 只判断成功响应信息
                if(httpRequest.readyState == 4 && httpRequest.status == 200){

                    // alert(httpRequest.responseText)
                    document.getElementById("myDiv").innerText = httpRequest.responseText

                }
                
            }


            // 3. 发送请求的方式和接收方
            // 第三个参数为是否异步,true 异步
            httpRequest.open("get","/ajaxTest",true)

            // 4. 发送请求
            httpRequest.send()
        }

    </script>
</html>

jquery中的ajax请求

$.get() $.post()

package com.lx.servlet.ajaxTest;

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

        String name = req.getParameter("name");
        System.out.println(name);

        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write(name);
    }
}





// springboot版本
package com.example.javasestudy;


import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin
@RestController
public class AjaxStudy {


    @GetMapping("ajaxStudy")
    public String ajaxStudy(@RequestParam("name") String name){

        return name;
    }
}
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试ajax</title>

		<script type="text/javascript" src="js/jquery-1.12.4.js"></script>
	</head>
	<body>

		<input type="text" id="username"/>
		<input type="button" id="btn" value="jquery形式的get异步请求" onclick="fun()">
		<div id="myDiv"></div>
	</body>

	<script type="text/javascript">
		function fun() {
			
			// url : 提交的服务器路径
			// data: 提交的数据 
			// params 参数列表
			// callback:回调函数,响应成功之后再去执行的函数。
			// type: 期望响应回来的数据类型。  
					// text 默认形式 文本形式。 
					// json形式。

			var url = "http://127.0.0.1:8080/ajaxStudy"

			var params = "name=" + $("#username").val()

			// $.post
			$.get(url, params,
				// 回调函数,如果响应成功就执行该函数,data代表服务器的响应数据
				function(data) {
					$("#myDiv").html(data);
				}, "text")
		}
	</script>
</html>

$.ajax()

$.get() $.post()的底层是$.ajax()

上层函数是对底层函数的封装,有较多的默认值。

$.get() $.post()简单易用,但是如果需要操作不常用的参数时,需要使用$.ajax()

// settings 配置集
	       
	// async : true异步 false同步 默认是异步
	// 
	// data  : 请求参数 params
	// 
	// dataType: 等同于type 期望响应回来的数据类型  默认text  json
    // 
	// success:成功之后的回调函数  function(data){}
    // 
	// error :  失败之后的回调函数 function(){} 
    // 
	// type: 提交方式 get |post  默认是get提交
$.ajax(url,[settings])
             
	     

使用方式 
 $.ajax({
     url:请求路径,
 data:请求参数
 ...
 ...

})
package com.lx.servlet.ajaxTest;

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

        String name = req.getParameter("name");
        System.out.println(name);

        System.out.println(1/0);

        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write(name);
    }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery形式的异步请求之get请求</title>

    <!--引入jquery文件-->
    <script src="../js/jquery-1.11.0.min.js" type="text/javascript"></script>
</head>
<body>

    <input type="button" id="btn" value="jquery形式的get异步请求" onclick="fun()">
    <div id="myDiv"></div>


</body>

    <script type="text/javascript">
        // 使用底层函数 来进行ajax异步请求操作
        function fun() {

            var url = "/jqueryAjaxGet"

            var params = "name=丽丽"

            $.ajax({
                url: url,
                data: params,
                type: "get",
                dataType: "text",
                success: function (data) {
                    $("#myDiv").html(data);
                },
                error: function () {
                    alert("error")
                }

            })

        }
    </script>
</html>

$.ajax()实例


$.ajax({
    url:"http://www.microsoft.com",    //请求的url地址
    dataType:"json",   //返回格式为json(期望服务器响应回来的数据形式)

// 还有text和xml,html
// html----浏览器会对返回的内容进行页面渲染,在freeMarker中,就是返回后端返回的那个页面
// text----纯文本,浏览器不会对返回的内容进行渲染,将html的内容文本原封不动的显示在浏览器上
    async:true,//请求是否异步,默认为异步,这也是ajax重要特性
    data:{"id":"value"},    //参数值,是一个json
    type:"GET",   //请求方式
    contentType: "application/json;charset=utf-8",
    // 解决跨域问题
    xhrFields: {withCredentials: true},
    beforeSend:function(){
        //请求前的处理
    },
    success:function(data){
//回调函数 ,成功时返回的数据存在形参data里
        //请求成功时处理
    },
    complete:function(){
        //请求完成的处理
    },
    error:function(){
        //请求出错处理
    }
})

在这里插入图片描述

json

数据交互格式,同类的还有xml

// 对象
{"name":"lisi","age":12}

// 数组
[]

[{"name":"lisi","age":12},{"name":"lisi","age":12}]

{"fruit":["apple","banana","mango"]}

com.alibaba.fastjson.JSON

package com.example.javasestudy.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

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

public class FastJsonTest {

    public static void main(String[] args) {

        System.out.println("=====================对象==================================");
        System.out.println("=====================java对象 json字符串 互转===================");
        Student student = new Student("bob", 24);
        String str1 = JSON.toJSONString(student);
        // {"age":24,"name":"bob"}
        System.out.println(str1);

        Student stu1 = JSON.parseObject(str1, Student.class);
        // Student(name=bob, age=24)
        System.out.println(stu1);

        System.out.println("=====================java对象 json对象 互转===================");
        JSONObject jsonObject1 = (JSONObject) JSON.toJSON(student);
        System.out.println(jsonObject1.getString("name"));

        Student student2 = JSON.toJavaObject(jsonObject1, Student.class);
        // Student(name=bob, age=24)
        System.out.println(student2);


        System.out.println("=====================java集合 json集合 互转===================");
        List<Student> students = Arrays.asList(new Student("zs", 3), new Student("ls", 4));
        JSONArray jsonArrays = (JSONArray) JSON.toJSON(students);
        Object o = jsonArrays.get(0);
        System.out.println(o);

        List<Student> students1 = jsonArrays.toJavaList(Student.class);
        System.out.println(students1);

        // json字符串集合 转 json集合
        JSONArray jArray = JSON.parseArray(JSON.toJSONString(students));
        System.out.println(jArray);


		System.out.println("===============日期转换 localdatetime 和转换java对象的使用方式一样=======================");
    }

}

com.fasterxml.jackson

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>javase-study</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>javase-study</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

package com.example.javasestudy.json;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private String name;
    private Integer age;
    private String city;

    public User(String name, Integer age, String city) {
        this.name = name;
        this.age = age;
        this.city = city;
    }

    private LocalDateTime localDateTime;
}






package com.example.javasestudy.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.util.*;

@SpringBootTest
public class JacksonTest {

    // registerModule(new JavaTimeModule()) jackson默认不能对localDatetime解析,加上这个就可以了
    private static ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());


    @Test
    public void test1() throws JsonProcessingException {

        System.out.println("============java对象 json字符串 互转===============");
        //对象转json
        User user = new User("tom",23,"上海");
        String json = objectMapper.writeValueAsString(user);
        System.out.println(json);
        //json转对象
        User uuser = objectMapper.readValue(json, User.class);
        System.out.println(uuser);

        // {"name":"tom","age":23,"city":"上海"}
        // User(name=tom, age=23, city=上海)


        System.out.println("============java对象 json对象 互转===============");
        User user3 = new User("tom",23,"上海");
        JsonNode jsonNode = objectMapper.valueToTree(user3);
        System.out.println(jsonNode);
        System.out.println(jsonNode.get("name"));

        User user4 = objectMapper.treeToValue(jsonNode, User.class);
        System.out.println(user4);


        System.out.println("===================java集合 json字符串 互转===========================");
        // 如果泛型的参数是基本类型的包装类,那么和 对象 json 互转的方式一样

        //list<User>转json
        List<User> ulist = new ArrayList<>();
        ulist.add(user);
        String ujson = objectMapper.writeValueAsString(ulist);
        System.out.println(ujson);
        //json转list<User>
        JavaType jt = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, User.class);
        List<User> urlist = objectMapper.readValue(ujson, jt);
        System.out.println(urlist);



        System.out.println("===================java集合 json集合 互转===========================");
        // 好像没有,是 objectMapper.createArrayNode() 创建一个json集合然后放进去,没有直接转的
        
        

        System.out.println("===================map===========================");

        // 如果泛型的参数是基本类型的包装类,那么和 对象 json 互转的方式一样

        //map<String,User>转json
        HashMap<String, User> umap = new HashMap<String, User>();
        umap.put(user.getName(), user);
        String mmjson = objectMapper.writeValueAsString(umap);
        System.out.println(mmjson);
        //json转map<String,User>
        // JavaType jvt = objectMapper.getTypeFactory().constructParametricType(HashMap.class,String.class,User.class);
        // 也可以这样
        Map<String,User> urMap = objectMapper.readValue(mmjson, new TypeReference<Map<String, User>>() {});
        System.out.println(urMap);


        System.out.println("===============忽略不存在的属性=======================");

        // 如果在进行 JSON 转 Java 对象时,JSON 中出现了 Java 类中不存在的属性,
        // 那么在转换时会遇到 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException 异常。
        String json2 = "{\"yyy\":\"xxx\",\"name\":\"LaoWang\",\"age\":28,\"skillList\":[\"java\",\"c++\"]}";
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        User user1 = objectMapper.readValue(json2, User.class);
        // User(name=LaoWang, age=28, city=null)
        System.out.printf(user1.toString());


        System.out.println("====================日期转换=====================");

        User user2 = new User("kk", 30, "北京", LocalDateTime.of(2024, 04, 22, 11, 16));
        String s = objectMapper.writeValueAsString(user2);
        // {"name":"kk","age":30,"city":"北京","localDateTime":[2024,4,22,11,16]}
        System.out.println(s);

        // User(name=kk, age=30, city=北京, localDateTime=2024-04-22T11:16)
        System.out.println(objectMapper.readValue(s, User.class));


    }
}


暂时只看fastjson和jackson,下面这两个用到再说

net.sf.json.JSONObject

对象的方法
// 将json串转换成java对象
JSONObject  JSONObject.fromObject(String s)	
// 对象通过key获取相应的值
String	getString(String s) 
// 将java对象换成json串
JSONObject  JSONObject.fromObject(String s).toString 
// 这个方法转换的json串值如果为null的话,转换过来不是null是字符串null
// 这个方法如果对象的属性是Date类型的话,它不会直接输出字符串,而是某个月的某个星期,某个星期的某天类似这样的;
// 而且这个方法会把你这个类中所有的属性都输出,而fastjson只会输出你赋值的属性。
// 关于输出日期的这个毛病,jackson同样存在。	

数组的方法
//将json串转换成java集合
JSONArray   JSONArray.fromObject(String s)	
//获取索引对应的对象
JSONObject  getJSONObject(int index)			
总结几点坑
  1. 当json数据的value为null时,转换成对象,获取该对象的value,使用==与null(null是代表空,不是字符串)比较,结果为false;
  2. 在Java对象转换JSON对象时,get开头的所有方法会被转换。
  3. 它把对象转换成json串的方式,把所有的属性包括为null的全部输出;尤其是日期,你输入一个yyyy-MM-dd类型日期,它会输出,日历类型,一年中的哪个月,一个月的哪天等等,总之不是我想要的。

Gson

输出的json数据要求跟原始javabean不一样以及日期的格式化

简单的javabean对象
package com.zhdw.mgrclient.test;
 
import java.util.Date;
 
public class Person {
    private String name;
    private int age;
    private Date birthday;
 
    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 Date getBirthday() {
        return birthday;
    }
 
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
测试类
package com.zhdw.mgrclient.test;
 
import java.util.Date;
 
import com.google.gson.Gson;
 
public class JSONTest {
 
    public static void main(String[] args) {
        Person hbk = new Person();
        hbk.setAge(30);
        hbk.setName("黄宝康");
        hbk.setBirthday(new Date());
        Gson gson = new Gson();
        String result = gson.toJson(hbk);
        System.out.println(result);
    }
}
输出结果
{"name":"黄宝康","age":30,"birthday":"May 21, 2018 11:50:23 AM"}

需求,我需要输出NAME,而不是小写的name,
第二,日期格式不是我想要的。

Gson针对这两个问题,提供了相关注解,只需要在Person的name字段加入相关注解即可。

@SerializedName("NAME")
private String name;

再次运行输出如下:可以看出name已经输出成NAME了,第一个问题解决。

{"NAME":"黄宝康","age":30,"birthday":"May 21, 2018 11:53:25 AM"}

使用GsonBuilder()构建Gson对象,而不是之前的new Gson();
这样运行输出了我们想要的格式。

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
{"NAME":"黄宝康","age":30,"birthday":"2018-05-21 11:57:16"}

部分内容引用自:
https://blog.csdn.net/huangbaokang/article/details/80390349

想了这几天,我想出唯一的解决之道了,我不能只喜欢老师,我要爱上他。
你爱的人要对你做什么都可以,不是吗?
思想是一种多么伟大的东西!
我是从前的我的赝品。
我要爱老师,否则我太痛苦了。

房思琪的初恋乐园
林奕含

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值