# ajax

# 基本概念

Ajax是ASynchronous JavaScript And XML(异步的JavaScript 和 XML),可异步完成网页局部刷新。异步指的是客户端不需要等待服务器端的响应,在服务器处理请求的过程中,客户端可以进行其他的操作。而同步指的是客户端必须等待服务器端的响应,在等待的期间客户端不能做其他操作。

# 实现方式

# 原生实现

服务器端ajaxServlet文件:

package SimpleLogin.service;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ajaxServlet
 */
@WebServlet("/ajaxServlet")
public class ajaxServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ajaxServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
        //1.获取请求参数
        //要想获取username的值,content-type需要设置为 application/x-www-form-urlencoded
        String username = request.getParameter("username");

        //处理业务逻辑。耗时
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //2.打印username
        System.out.println(username);

        //3.响应
        response.getWriter().write(" hello : " + username);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

原生ajax页面originalAjax.html:

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script>

            //定义方法
        function fun() {
            //发送异步请求
            //1.创建核心对象
            var xmlhttp;
            if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
                xmlhttp = new XMLHttpRequest();
            }
            else {// code for IE6, IE5
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }

            //2. 建立连接
            /*
                参数:
                    1. 请求方式:GET、POST
                        * get方式,请求参数在URL后边拼接。send方法为空参
                        * post方式,请求参数在send方法中定义
                    2. 请求的URL:
                    3. 同步或异步请求:true(异步)或 false(同步)

             */
            //xmlhttp.open("GET","ajaxServlet?username=tom",true);
            xmlhttp.open("POST", "ajaxServlet", true);
            xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

            //3.发送请求
            xmlhttp.send("username=xie");

            //4.接受并处理来自服务器的响应结果
            //获取方式 :xmlhttp.responseText

            //当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
            xmlhttp.onreadystatechange = function () {
                //判断readyState就绪状态是否为4,判断status响应状态码是否为200
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    //获取服务器的响应结果
                    var responseText = xmlhttp.responseText;
                    alert(responseText);
                }
            }

        }

    </script>


    </head>

    <body>

        <input type="button" value="发送异步请求" onclick="fun();">

        <input>
    </body>

</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

# jQuery实现

jQuery封装好了库,我们可以直接调用,ajax调用:

$.ajax({
    url:"ajaxServlet1111" , // 请求路径
    type:"POST" , //请求方式
    //data: "username=jack&age=23",//请求参数
    data:{"username":"jack","age":23},
    success:function (data) {
        alert(data);
    },//响应成功后的回调函数
    error:function () {
        alert("出错啦...")
    },//表示如果请求响应出现错误,会执行的回调函数

    dataType:"text"//设置接受到的响应数据的格式
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

get方法调用:

$.get("ajaxServlet",{username:"rose"},function (data) {
    alert(data);
},"json");
1
2
3

post方法调用:

$.post("ajaxServlet",{username:"rose"},function (data) {
    alert(data);
},"json");

$.post({
    url: "webGetGPS",
    data: {
        currentTime: getISO8601(),
        lastAnimTime: lastAnimTimeVar
    },
    dataType: "json"
})
.done(function(data) {
    console.log(data);
})
.fail(function(data) {
    console.log(data);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# json相关

json是JavaScript Object Notation(JavaScript 对象记法),用于存储和交换文本信息,类似xml,但是json比xml更小,更快,更易解析。

# json数据类型

json中的数据类型和javascript中的数据类型基本对应:

json对象 javascript对象
number number
boolean boolean
string string
null null
array array,[]
object object,{}

注意json中的字符串必须使用双引号,Object中的键也必须用双引号。

# json数据结构

json中有两种数据结构:

  1. 对象:无序的结构,键值对的组合形式。
  2. 数组:有序的机构。

# json获取数据

在json中获取数据方式有:

  1. json对象.键名
  2. json对象["键名"]
  3. 数组对象[索引]
  4. 遍历

实例如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        //1.定义基本格式
        var person = { "name": "张三", age: 23, 'gender': true };

        //遍历person对象
        for (var key in person) {
            //这样的方式获取不行。因为相当于  person."name"
            console.log(key + ":" + person.key);
            console.log(key + ":" + person[key]);
        }

        //获取name的值
        console.log(person.name);
        console.log(person["name"]);

        //2.嵌套格式   {}———> []
        var persons = {
            "persons": [
                { "name": "张三", "age": 23, "gender": true },
                { "name": "李四", "age": 24, "gender": true },
                { "name": "王五", "age": 25, "gender": false }
            ]
        };
        //获取王五值
        var name1 = persons.persons[2].name;
        console.log(name1);


        //3.嵌套格式   []———> {}
        var ps = [{ "name": "张三", "age": 23, "gender": true },
        { "name": "李四", "age": 24, "gender": true },
        { "name": "王五", "age": 25, "gender": false }];
        //获取第二个人的值
        console.log(ps[1].name);
        //遍历所有人的值
        for (var i = 0; i < ps.length; i++) {
            var p = ps[i];
            for (var key in p) {
                console.log(key + ":" + p[key]);
            }
        }


    </script>

</head>

<body>

</body>

</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

# java处理json

java服务端解析json有几种第三方库:Jsonlib,Gson,fastjson,jackson。这里以jackson为例来进行解析。

java解析json主要有两种方式:

  1. JSON转为Java对象,操作步骤主要有:
    1. 导入jackson的相关jar包
    2. 创建Jackson核心对象 ObjectMapper
    3. 调用ObjectMapper的相关方法进行转换:readValue(json字符串数据,Class)
  2. Java对象转换JSON,操作步骤主要有:
    1. 导入jackson的相关jar包
    2. 创建Jackson核心对象 ObjectMapper
    3. 调用ObjectMapper的相关方法进行转换
      1. 转换方法:

        • writeValue(参数1,obj),参数1可以是:
          • File:将obj对象转换为JSON字符串,并保存到指定的文件中
          • Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
          • OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
        • writeValueAsString(obj):将对象转为json字符串
      2. 注解:

        1. @JsonIgnore:排除属性。
        2. @JsonFormat:属性值得格式化。@JsonFormat(pattern = "yyyy-MM-dd")
      3. 复杂java对象转换

        1. List:数组
        2. Map:对象

实例操作如下:

Person.java内容:

import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Date;

public class Person {

    private String name;
    private int age;
    private String gender;

    // @JsonIgnore // 忽略该属性
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = 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 String getGender() {
        return gender;
    }

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

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + '}';
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

Main.java内容:

import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) {
        try {
            test1();
            test2();
            test3();
            test4();
            test5();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    // Java对象转为JSON字符串
    public static void test1() throws Exception {
        // 1.创建Person对象
        Person p = new Person();
        p.setName("张三");
        p.setAge(23);
        p.setGender("男");

        // 2.创建Jackson的核心对象 ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        // 3.转换
        String json = mapper.writeValueAsString(p);
        System.out.println(json);

        // writeValue,将数据写到d:\a.txt文件中
        mapper.writeValue(new File("d://a.txt"),p);

        // writeValue.将数据关联到Writer中
        mapper.writeValue(new FileWriter("d://b.txt"), p);
    }

    //Java对象转换为JSON字符串时,JSONFormat格式化date数据
    public static void test2() throws Exception {
        // 1.创建Person对象
        Person p = new Person();
        p.setName("张三");
        p.setAge(23);
        p.setGender("男");
        p.setBirthday(new Date());

        // 2.转换
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(p);

        System.out.println(json);
    }

    //Java ArrayList数组转换为json字符串
    public static void test3() throws Exception {
        // 1.创建Person对象
        Person p = new Person();
        p.setName("张三");
        p.setAge(23);
        p.setGender("男");
        p.setBirthday(new Date());

        Person p1 = new Person();
        p1.setName("张三");
        p1.setAge(23);
        p1.setGender("男");
        p1.setBirthday(new Date());

        Person p2 = new Person();
        p2.setName("张三");
        p2.setAge(23);
        p2.setGender("男");
        p2.setBirthday(new Date());

        // 创建List集合
        List<Person> ps = new ArrayList<Person>();
        ps.add(p);
        ps.add(p1);
        ps.add(p2);

        // 2.转换
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(ps);
        // [{},{},{}]
        System.out.println(json);
    }

    //Java hashMap转化为json字符串
    public static void test4() throws Exception {
        // 1.创建map对象
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("name", "张三");
        map.put("age", 23);
        map.put("gender", "男");

        // 2.转换
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(map);
        System.out.println(json);
    }

    //JSON字符串转为Java对象
    public static void test5() throws Exception {
        // 1.初始化JSON字符串
        String json = "{\"gender\":\"男\",\"name\":\"张三\",\"age\":23}";

        // 2.创建ObjectMapper对象
        ObjectMapper mapper = new ObjectMapper();
        // 3.转换为Java对象 Person对象
        Person person = mapper.readValue(json, Person.class);

        System.out.println(person);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

# json实例-检测用户名

在填写表单时,检测用户名是否已经被别人注册,如果被注册则提示已被注册。有一个问题需要注意下:服务器响应的数据,在客户端使用时,要想当做json数据格式使用。有两种解决方案:

  1. $.get,$.post将参数type指定为"json",$.ajax将dataType指定为"json"。
  2. 在服务器端设置MIME类型:response.setContentType("application/json;charset=utf-8");

下面是服务器端代码,FindUserServlet.java:

package SimpleLogin.service;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/findUserServlet")
public class FindUserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 1.获取用户名
        String username = request.getParameter("username");

        // 2.调用service层判断用户名是否存在

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

        // 设置响应的数据格式为json
        response.setContentType("application/json;charset=utf-8");
        Map<String, Object> map = new HashMap<String, Object>();

        if ("xie".equals(username)) {
            // 存在
            map.put("userExsit", true);
            map.put("msg", "此用户名太受欢迎,请更换一个");
        } else {
            // 不存在
            map.put("userExsit", false);
            map.put("msg", "用户名可用");
        }

        // 将map转为json,并且传递给客户端
        ObjectMapper mapper = new ObjectMapper();
        // 并且传递给客户端
        mapper.writeValue(response.getWriter(), map);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doPost(request, response);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

下面是浏览器端页面register.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>注册页面</title>
        <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.js"></script>


        <script>
            //在页面加载完成后
        $(function () {
           //给username绑定blur事件
           $("#username").blur(function () {
               //获取username文本输入框的值
               var username = $(this).val();
               //发送ajax请求
               //期望服务器响应回的数据格式:{"userExsit":true,"msg":"此用户名太受欢迎,请更换一个"}
               //                         {"userExsit":false,"msg":"用户名可用"}
               $.get("findUserServlet",{username:username},function (data) {
                   //判断userExsit键的值是否是true

                   // alert(data);
                   var span = $("#s_username");
                   if(data.userExsit){
                       //用户名存在
                       span.css("color","red");
                       span.html(data.msg);
                   }else{
                       //用户名不存在
                       span.css("color","green");
                       span.html(data.msg);
                   }
               });

           }); 
        });

    </script>
    </head>
    <body>


        <form>

            <input type="text" id="username" name="username" placeholder="请输入用户名">
            <span id="s_username"></span>
            <br>
            <input type="password" name="password" placeholder="请输入密码"><br>
            <input type="submit" value="注册"><br>

        </form>

    </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# json实例-百度搜索

做一个类似百度搜索框,根据打出的东西自动补充相关内容。

服务器端处理ajax过程,ajaxBaiduSelect.jsp:

<%@ page contentType="text/html;charset=utf-8"%>
<%@ page import="java.io.UnsupportedEncodingException"%>
<%@ page import="java.sql.*"%>
<%
String driver = "org.mariadb.jdbc.Driver";

String url = "jdbc:mysql://10.0.10.150:6612/test";

String user = "root";
String password = "666666";

try {

    Class.forName(driver);

    Connection conn = DriverManager.getConnection(url, user, password);

    if (conn.isClosed())

        out.println("failed to connect to the Database!");

    Statement statement = (Statement) conn.createStatement();

    String sql = "select name,number from person where name like '" + request.getParameter("name") + "%'";

    ResultSet rs = statement.executeQuery(sql);

    String name = null;
    String returnvalue = null;
    while (rs.next()) {
        name = rs.getString("name");

        //name = new String(name.getBytes("ISO-8859-1"), "GB2312");

        if (returnvalue == null)
    returnvalue = "{\"name\":\"" + name + "\",\"number\":\"" + rs.getString("number") + "\"}";
        else
    returnvalue = returnvalue + ",{\"name\":\"" + name + "\",\"number\":\"" + rs.getString("number") + "\"}";

    }

    returnvalue = "[" + returnvalue + "]";
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Cache-Control", "no-cache");
    java.io.PrintWriter pw = null;
    pw = response.getWriter();
    pw.write(returnvalue);
    pw.close();

    rs.close();
    conn.close();

} catch (ClassNotFoundException e) {
    out.println(e);
} catch (SQLException e) {
    out.println(e);
} catch (UnsupportedEncodingException e) {
    out.println(e);
}
%>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

浏览器端请求页面baidu.html:

<!DOCTYPE html>

<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script language="javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.js"></script>
        <script>
            $(document).ready(function(){
                    $("#searchinput").on('input propertychange',function(){
                        var chastring;
                        chastring = $("#searchinput").val();
                        
                            $.ajax({
                                type:"POST",
                                url:"ajaxBaiduSelect.jsp",
                                data:{name:chastring},
                                success:function(data){
                                    var divstring=null;
                                    
                                    function getElements(name) { var returns = document.getElementsByName(name); if (returns.length > 0) return returns; returns = new Array(); var e = document.getElementsByTagName('div'); for (i = 0; i < e.length; i++) { if (e[i].getAttribute("name") == name) { returns[returns.length] = e[i]; } } return returns; }

                                    
                                    for(var i in data){
                                        if(divstring == null)divstring="<div name=\"searchli\" style=\"cursor:help\">"+data[i].name+"		number:"+ data[i].number+"</div>";
                                        else
                                        divstring = divstring+"<div name=\"searchli\" style=\"cursor:help\">"+data[i].name+"		number:"+ data[i].number+"</div>";
                                    };
                                    $("#search").empty();
                                    $("#search").html(divstring);

                                    $("[name='searchli']").mouseover(function(){
                                       $(this).css("background","red");
                                    });
                                    $("[name='searchli']").mouseout(function(){
                                        $(this).css("background","white");
                                    });
                                   
                                   var one = getElements("searchli");
                                    
                                    
                                   for(var i in one){
                                        one[i].onmousedown=function(){
                                        if(navigator.userAgent.indexOf("Firefox")>0){
                                            
                                            
                                            document.getElementById("searchinput").value = this.textContent;
                                            //$("#searchinput").attr("value",this.textContent);
                                            }
            
                                        if(navigator.userAgent.indexOf('MSIE') >= 0){
                                
                                        $("#searchinput").attr("value",this.innerHTML);
                                            }

                                                }
                                            }

//									$(".searchli").on("click",function(){
//										alert("ok");
//									   var a;
//										a = $(this).text();
//										$("#searchinput").attr("value",a);
//									});
                                    
                                },
                                error:function(data){
                                    alert("error");
                                },
                                datatype:"json"
                            });
                    
                    });

                    $("#searchinput").blur(function(){
                        $("#search").hide();
                    });
                    $("#searchinput").focus(function(){
                         $("#search").show();
                    });
                        
         
                    
                    
                   
                     
                    
                    $("#search").css("width",$("#searchinput").css("width"));
               
            });
        </script>
    </head>
    <body>
        <div>查看百度提示信息</div>
        <input type="text" id="searchinput" style="width: 200px">
        <div id="search" style="border: 1px solid black" hidden="hidden"></div>

    </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100