JSON和AJAX

今日内容

  1. 1JSON解析
  2. 2、什么是Ajax
  3. 3Ajax工作原理
  4. 4Ajax的使用
  5. 5Ajax的综合练习

教学目标

  1. 1、掌握JSON解析
  2. 2、熟悉什么是Ajax
  3. 3、掌握Ajax工作原理
  4. 4、掌握Ajax的使用
  5. 5、熟练Ajax的综合练习

第一节 JSON概述

1.1 什么是json

JSON(JavaScript Object Notation, JS 对象表示) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于机器解析和生成,并有效地提升网络传输效率。

1.2 json语法

[] 表示数组

{} 表示对象

“” 表示是属性名或字符串类型的值

: 表示属性和值之间的分隔符

, 表示多个属性的间隔符或者是多个元素的间隔符

json的值:

  • 数字(整数或浮点数)
  • 字符串(在双引号或单引号中)
  • 逻辑值(true 或 false)
  • 数组(在中括号中)
  • 对象(在大括号中)
  • null

实例演示:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>json语法</title>
  6. </head>
  7. <body>
  8. <script type="text/javascript">
  9. //表示对象
  10. var p=new Object();
  11. p.name="haha";
  12. p.age=20;
  13. p.address="beijing";
  14. console.log(p.name+"..."+p.age+"...."+p.address);
  15. var p1={"name":"李四","age":30,"address":"上海"};
  16. console.log(p1.name+"..."+p1.age+"...."+p1.address);
  17. var json='{"name":"李四","age":30,"address":"杭州"}';//json字符串
  18. var p2=JSON.parse(json);
  19. console.log(p2.name+"..."+p2.age+"...."+p2.address);
  20. //要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
  21. //var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
  22. //要实现从 JSON 转换为对象,使用 JSON.parse() 方法:
  23. //var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
  24. //表示数组
  25. var arr=["北京","上海","南京"];
  26. var arr2=[{name:"xxx",age:20},{name:"yyy",age:22},{name:"zzz",age:30}];
  27. </script>
  28. </body>
  29. </html>

第二节 JSON解析

要解析的字符串:

  1. //对象嵌套数组嵌套对象
  2. String json1="{'id':1,'name':'JAVAEE-1910','stus':[{'id':101,'name':'刘一','age':16}]}";
  3. //数组
  4. String json2="['北京','天津','杭州']";

初始的类:

Student.java

  1. public class Student {
  2. private int id;
  3. private String name;
  4. private int age;
  5. public int getId() {
  6. return id;
  7. }
  8. public void setId(int id) {
  9. this.id = id;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public int getAge() {
  18. return age;
  19. }
  20. public void setAge(int age) {
  21. this.age = age;
  22. }
  23. public Student(int id, String name, int age) {
  24. super();
  25. this.id = id;
  26. this.name = name;
  27. this.age = age;
  28. }
  29. public Student() {
  30. super();
  31. }
  32. @Override
  33. public String toString() {
  34. return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
  35. }
  36. }

Grade.java

  1. public class Grade {
  2. private int id;
  3. private String name;
  4. private ArrayList<Student> stus;
  5. public Grade(int id, String name, ArrayList<Student> stus) {
  6. super();
  7. this.id = id;
  8. this.name = name;
  9. this.stus = stus;
  10. }
  11. public Grade() {
  12. super();
  13. }
  14. @Override
  15. public String toString() {
  16. return "Grade [id=" + id + ", name=" + name + ", stus=" + stus + "]";
  17. }
  18. public int getId() {
  19. return id;
  20. }
  21. public void setId(int id) {
  22. this.id = id;
  23. }
  24. public String getName() {
  25. return name;
  26. }
  27. public void setName(String name) {
  28. this.name = name;
  29. }
  30. public ArrayList<Student> getStus() {
  31. return stus;
  32. }
  33. public void setStus(ArrayList<Student> stus) {
  34. this.stus = stus;
  35. }
  36. }

2.1 FastJson解析
  1. public class FASTJson {
  2. //解析
  3. @Test
  4. public void test1() {
  5. // 对象嵌套数组嵌套对象
  6. String json1 = "{'id':1,'name':'JAVAEE-1703','stus':[{'id':101,'name':'刘铭','age':16}]}";
  7. // 数组
  8. String json2 = "['北京','天津','杭州']";
  9. //1、
  10. //静态方法转成对象
  11. Grade grade=JSON.parseObject(json1, Grade.class);
  12. System.out.println(grade);
  13. //转成数组
  14. List<String> list=JSON.parseArray(json2, String.class);
  15. System.out.println(list);
  16. }
  17. //生成
  18. @Test
  19. public void test2(){
  20. ArrayList<Student> list=new ArrayList<>();
  21. for(int i=1;i<3;i++){
  22. list.add(new Student(101+i, "码子", 20+i));
  23. }
  24. Grade grade=new Grade(100001,"张三", list);
  25. String json=JSON.toJSONString(grade);
  26. System.out.println(json);
  27. }
  28. }
  29. //注意事项
  30. //1.1控制不序列化某些属性 @JSONField(serialize=false) 默认是true
  31. //1.2控制输出
  32. // SerializerFeature.PrettyFormat
  33. // SerializerFeature.WriteMapNullValue null也输出
  34. // SerializerFeature.WriteNullStringAsEmpty null输出""
  35. // 循环引用检测 SerializerFeature.DisableCircularReferenceDetect

2.2 Jackson解析
  1. import com.fasterxml.jackson.core.type.TypeReference;
  2. public class JackSonTest {
  3. //解析
  4. @Test
  5. public void test1() throws Exception{
  6. // 对象嵌套数组嵌套对象
  7. String json1 = "{\"id\":1,\"name\":\"JAVAEE-1703\",\"stus\":[{\"id\":101,\"name\":\"刘一\",\"age\":16}]}";
  8. // 数组
  9. String json2 = "[\"北京\",\"天津\",\"杭州\"]";
  10. //1、创建对象映射
  11. ObjectMapper mapper=new ObjectMapper();
  12. Grade grade=mapper.readValue(json1, Grade.class);
  13. System.out.println(grade);
  14. //2、
  15. ArrayList<String> list=mapper.readValue(json2,
  16. new TypeReference<ArrayList<String>>() {
  17. });
  18. System.out.println(list);
  19. }
  20. //生成
  21. @Test
  22. public void test2() throws JsonProcessingException{
  23. ArrayList<Student> list=new ArrayList<>();
  24. for(int i=1;i<3;i++){
  25. list.add(new Student(101+i, "码子", 20+i));
  26. }
  27. Grade grade=new Grade(100001,"张三", list);
  28. ObjectMapper mapper=new ObjectMapper();
  29. //将对象转换为JSON格式字符串
  30. String json=mapper.writeValueAsString(grade);
  31. System.out. println(json);
  32. }
  33. }
  34. //Jackson注解
  35. //1 @JsonProperty注解指定一个属性用于JSON映射,默认情况下映射的JSON属性与注解的属性名称相同,不过可以使用该注解的value值修改JSON属性名
  36. //2 @JsonIgnore注解用于排除某个属性,这样该属性就不会被Jackson序列化和反序列化。
  37. //3 格式化输出
  38. // 美化输出
  39. //mapper.enable(SerializationFeature.INDENT_OUTPUT);
  40. // 允许序列化空的POJO类(否则会抛出异常)
  41. //mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

第三节 Ajax概述

AJAX 是一种在无需重新加载整个网页的情况下,能够实现局部更新的技术。

3.1 什么是AJAX

AJAX = 异步 JavaScript 和 XML。 (Asynchronized JavaScript And XML)

AJAX 是一种用于创建快速动态网页的技术。

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

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

有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。

3.2 AJAX工作原理

image.png

AJAX是基于现有的Internet标准,并且联合使用它们:

  • XMLHttpRequest 对象 (异步的与服务器交换数据)
  • JavaScript/DOM (信息显示/交互)
  • CSS (给数据定义样式)
  • XML (作为转换数据的格式)、JSON

3.3 AJAX实例

使用Ajax发送请求四个步骤:

1 创建XMLHTTPRequest对象

2 设置onreadystatechange回调函数

3 open() 打开连接

4 send() 发送请求

div 部分用于显示来自服务器的信息。当按钮被点击时,它负责调用名为 loadXMLDoc() 的函数:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>ajax实例</title>
  5. <meta charset="utf-8"/>
  6. <script type="text/javascript">
  7. function loadXMLDoc()
  8. {
  9. //1 创建XMLHTTPRequest对象
  10. var xhr;
  11. if(window.XMLHttpRequest){
  12. xhr=new XMLHttpRequest();
  13. }else{
  14. //ie
  15. xhr=new ActiveXObject("Microsoft.XMLHTTP");
  16. }
  17. //2 设置onreadystatechange回调函数(异步,如果同步不需要)
  18. xhr.onreadystatechange=function(){
  19. //处理数据 readyState==4表示服务器响应完毕 状态码 200 404 500 302
  20. if(xhr.readyState==4&&xhr.status==200){
  21. document.getElementById("mydiv").innerHTML=xhr.responseText;
  22. }
  23. }
  24. //3 open() 打开连接 method(GET POST) url(表示请求的地址) async(同步或异步 true异步,false同步)
  25. xhr.open("GET","book.xml",true);
  26. //4 send() 发送请求
  27. xhr.send();
  28. }
  29. </script>
  30. </head>
  31. <body>
  32. <div id="myDiv"><h2>使用 AJAX 修改该文本内容</h2></div>
  33. <button type="button" onclick="loadXMLDoc()">修改内容</button>
  34. </body>
  35. </html>

book.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <books>
  3. <book>
  4. <id>1101</id>
  5. <bookname>java开发</bookname>
  6. <author>徐廉政</author>
  7. <price>99</price>
  8. </book>
  9. <book>
  10. <id>1102</id>
  11. <bookname>HTML开发</bookname>
  12. <author>张健</author>
  13. <price>100</price>
  14. </book>
  15. </books>

3.4 创建XMLHttpRequest对象

XMLHttpRequest对象是AJAX的基础。
所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。
XMLHttpRequest 用于在后台与服务器交互数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。创建 XMLHttpRequest 对象的语法:

  1. var xmlhttp=new XMLHttpRequest();

老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:

  1. var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

为了应对所有的现代浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject :

  1. var xmlhttp;
  2. if (window.XMLHttpRequest)
  3. {
  4. // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
  5. xmlhttp=new XMLHttpRequest();
  6. }
  7. else
  8. {
  9. // IE6, IE5 浏览器执行代码
  10. xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  11. }

3.5 onreadystatechange回调函数

当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当 readyState 改变时,就会触发 onreadystatechange 事件。readyState 属性存有 XMLHttpRequest 的状态信息。
下面是 XMLHttpRequest 对象的三个重要的属性:

属性 描述
onreadystatechange 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。0: 请求未初始化1: 服务器连接已建立2: 请求已接收3: 请求处理中4: 请求已完成,且响应已就绪
status 200: “OK”404: 未找到页面

在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。

当 readyState 等于 4 且状态为 200 时,表示响应已就绪:

  1. xmlhttp.onreadystatechange=function()
  2. {
  3. if (xmlhttp.readyState==4 && xmlhttp.status==200)
  4. {
  5. document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
  6. }
  7. }

注意: onreadystatechange 事件被触发 4 次, 五个状态(0 - 4),对应着 readyState 的每个变化。

3.5 XMLHttpRequest请求

如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:

  1. xmlhttp.open("GET","servlet1",true);
  2. xmlhttp.send();
方法 描述
open(method,url,async) 规定请求的类型、URL 以及是否异步处理请求。method:请求的类型;GET 或 POSTurl:文件在服务器上的位置async:true(异步)或 false(同步)
send(string) 将请求发送到服务器。string:仅用于 POST 请求

method-请求方式

GET 还是 POST?

与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。

然而,在以下情况中,请使用 POST 请求:

  • 不使用缓存文件(更新服务器上的文件或数据库)
  • 向服务器发送大量数据(POST 没有数据量限制)
  • 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

GET 请求

一个简单的 GET 请求:

  1. xmlhttp.open("GET","/try/ajax/servlet3",true);
  2. xmlhttp.send();

在上面的例子中,您可能得到的是缓存的结果。

为了避免这种情况,请向 URL 添加一个唯一的 ID:

  1. xmlhttp.open("GET","/try/ajax/servlet3?number=" + Math.random(),true);
  2. xmlhttp.send();

如果您希望通过 GET 方法发送信息,请向 URL 添加信息:

  1. xmlhttp.open("GET","/try/ajax/servlet3?username=leilei&password=123",true);
  2. xmlhttp.send();

POST 请求

一个简单 POST 请求:

  1. xmlhttp.open("POST","/try/ajax/servlet4",true);
  2. xmlhttp.send();

如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:

  1. xmlhttp.open("POST","/try/ajax/servlet4",true);
  2. xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  3. xmlhttp.send("username=leilei&password=123");
方法 描述
setRequestHeader(header,value) 向请求添加 HTTP 头。header: 规定头的名称 value: 规定头的值

url - 服务器地址

open() 方法的 url 参数是服务器上资源的地址:

  1. xmlhttp.open("GET","servlet5",true);

异步 - True 或 False

AJAX 指的是异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。
XMLHttpRequest 对象如果要用于 AJAX 的话,其 open() 方法的 async 参数必须设置为 true:

  1. xmlhttp.open("GET","ajax_test.html",true);

对于 web 开发人员来说,发送异步请求是一个巨大的进步。很多在服务器执行的任务都相当费时。AJAX 出现之前,这可能会引起应用程序挂起或停止。

通过 AJAX,JavaScript 无需等待服务器的响应,而是:

  • 在等待服务器响应时执行其他脚本
  • 当响应就绪后对响应进行处理

Async=true

当使用 async=true 时,请规定在响应处于 onreadystatechange 事件中的就绪状态时执行的函数:

  1. xmlhttp.onreadystatechange=function()
  2. {
  3. if (xmlhttp.readyState==4 && xmlhttp.status==200)
  4. {
  5. document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
  6. }
  7. }
  8. xmlhttp.open("GET","/try/ajax/ajax_info.txt",true);
  9. xmlhttp.send();

Async=false

如需使用 async=false,请将 open() 方法中的第三个参数改为 false:

我们不推荐使用 async=false,但是对于一些小型的请求,也是可以的。

请记住,JavaScript 会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢,应用程序会挂起或停止。

注意:当您使用 async=false 时,请不要编写 onreadystatechange 函数 - 把代码放到 send() 语句后面即可:

  1. xmlhttp.open("GET","/try/ajax/ajax_info.txt",false);
  2. xmlhttp.send();
  3. document.getElementById("myDiv").innerHTML=xmlhttp.responseText;

3.6 XMLHttpRequest响应

服务器响应

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。

属性 描述
responseText 获得字符串形式的响应数据。
responseXML 获得 XML 形式的响应数据。

responseText 属性

如果来自服务器的响应并非 XML,请使用 responseText 属性。

responseText 属性返回字符串形式的响应,因此您可以这样使用:

  1. document.getElementById("myDiv").innerHTML=xmlhttp.responseText;

responseXML 属性

如果来自服务器的响应是 XML,而且需要作为 XML 对象进行解析,请使用 responseXML 属性:

  1. xmlDoc=xmlhttp.responseXML;
  2. txt="";
  3. x=xmlDoc.getElementsByTagName("ARTIST");
  4. for (i=0;i<x.length;i++)
  5. {
  6. txt=txt + x[i].childNodes[0].nodeValue + "<br>";
  7. }
  8. document.getElementById("myDiv").innerHTML=txt;

第四节 Ajax的使用

4.1 Ajax与服务器交互
  • 模拟登陆验证

    验证用户是否可以注册!利用ajax技术进行动态验证


1.编写注册页面

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <%
  3. String path = request.getContextPath();
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  5. %>
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  7. <html>
  8. <head>
  9. <base href="<%=basePath%>">
  10. <title>My JSP 'index.jsp' starting page</title>
  11. <meta http-equiv="pragma" content="no-cache">
  12. <meta http-equiv="cache-control" content="no-cache">
  13. <meta http-equiv="expires" content="0">
  14. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  15. <meta http-equiv="description" content="This is my page">
  16. <script type="text/javascript" src="./ajax.js"></script>
  17. <!--
  18. <link rel="stylesheet" type="text/css" href="styles.css">
  19. -->
  20. </head>
  21. <body>
  22. <center>
  23. <font color="red" size="7">qq注册页面</font>
  24. <input type="text" name="username" onkeyup="kp(this)" /> <span id="sp"></span> <br/>
  25. <input type="password" name="password"/><br/>
  26. <input type="submit" value="注册"/>
  27. </center>
  28. <script type="text/javascript">
  29. //当用户名输入框输入内容就调用此方法
  30. function kp(ipt){
  31. //1.获取input输入框的value
  32. var value = ipt.value;
  33. //2.进行验证
  34. if(value != null && value !=""){
  35. //1-5
  36. //1.创建Ajax
  37. var xmlhttp = getAjax();
  38. //2.设置状态改变监听
  39. xmlhttp.onreadystatechange = function(){
  40. //5获取响应数据
  41. if(xmlhttp.readyState == 4 && xmlhttp.status ==200)
  42. {
  43. var result = xmlhttp.responseText; //获取结果
  44. // 1 行 2 不行
  45. //1.找到span标签
  46. var sp = document.getElementById("sp");
  47. if(result == "1"){
  48. //成功的 span 提示一句绿色的话
  49. sp.innerHTML=""; //清空
  50. var ft = document.createElement("font");
  51. var fttext = document.createTextNode("恭喜您!可以注册!!"); //文本标签
  52. ft.setAttribute("color", "green");
  53. ft.appendChild(fttext);
  54. sp.appendChild(ft);
  55. }else{
  56. //失败的 span 提示一句红色的话
  57. sp.innerText="用户已经被注册!";
  58. sp.style.color = "red";
  59. }
  60. }
  61. }
  62. //3.设置ajax method url
  63. xmlhttp.open("POST",
  64. "${pageContext.request.contextPath}/servlet/DealServlet");
  65. //4.发送请求
  66. //设置一个请求头
  67. xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  68. xmlhttp.send("value="+value);
  69. }
  70. }
  71. </script>
  72. </body>
  73. </html>

4.2 编写Ajax处理servlet
public class DealServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //0.设置编码格式
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //1.
        String value = request.getParameter("value");
        //2.
        String  result = null;
        if (value.equals("root") | value.equals("admin")) {
           result = "2";
           //代表已经存在
        }else{
            //可以注册
            result = "1";
        }
        //3.
        response.getWriter().write(result);   
    }    
}

作业题

1、使用Ajax实现进行数据的异步提交和结果回显
2、请完成下列数据的解析
{
    "state": "success",
    "code": "0",
    "data": {
        "acc": 100,
        "city": "北京市",
        "dist": "通州区",
        "addr": "北京市通州区永乐店镇北京金篮子生态种植有限公司",
        "prov": "北京市",
        "lon": 116.82106018,
        "number": "13",
        "town": "永乐店镇",
        "street": "永乐大街",
        "lat": 39.69581985
    }
}
3、自己创建一张表   2个字段  username   password
    编写MVC+ajax。实现用户名框失去焦点,数据库验证用户名是否存在。给出相应的提示!

面试题

1、为什么要用ajax
2、请介绍一下XMLhttprequest对象
3、Ajax和javascript的区别
4、请描述json的作用
5、请写出常用的json解析技术