文章目录
  1. 1. 同步和异步
  2. 2. AJAX
  3. 3. 与服务器通信
  4. 4. XMLHttpRequest 对象方法
  5. 5. XMLHttpRequest 对象属性
  6. 6. 案例校验用户名
  7. 7. JSON
    1. 7.1. JSONlib 使用
    2. 7.2. FlexJson
  8. 8. 服务器返回xml
    1. 8.1. xstream
    2. 8.2. 使用XML 注解
  9. 9. Tip

同步和异步

同步: 提交请求 -> 等待服务器处理 -> 处理完毕返回 -> 这期间客户端不能干任何事

异步: 请求通过事件出发 -> 服务器处理(浏览器可以做其他事) -> 处理完毕返回

AJAX

AJAX: Asynchronous Javascript and XML, 允许浏览器和服务器通信而无须刷新 当前页面的技术, 与服务器无关

核心是JavaScript对象: XmlHttpRequest

与服务器通信

服务端

1
2
3
4
5
6
7
8
9
10
11
// ServletDemo
public void doGet(req, resp) {
    resp.setContentType("text/xml;charset=utf-8");
    PrintWriter out = resp.getWriter();
    
    // 返回 xml
    SAXReader reader = new SAXReader();
    Document document = reader.read(path);
    String xml = document.asXML();
    out.write(xml);
}

客户端

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
function createXmlHttpRequest(){
    var xmlHttp;
    try{
        xmlHttp = new XMLHttpRequest();
    } catch(e) {
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e){
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch(e){}
    }
    return xmlHttp;
}
window.onload = function(){ // 当页面被全部记载完毕后再执行
    document.getElementById("b1").onclick = function(){
        // 创建 XMLHttpRequest 对象
        var xhr = createXmlHttpRequest();
        
        // xhr的readyState 改变都会触发 onreadystatechange 事件
        // 0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法) 
        // 1 (初始化) 对象已建立,尚未调用send方法 
        // 2 (发送数据) send方法已调用,但是当前的状态及http头未知 
        // 3 (数据传送中) 已接收部分数据,因为响应及http头不全,
        // 4 (完成) 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据 
        xhr.onreadystatechange = function() {
            if(xhr.readyState == 4) {
                // 数据正确返回
                if(xhr.status==200 || xhr.status ==304){
                    // 如果返回是文本数据
                    var data = xhr.responseText;
                    // 如果返回是 xml
                    // 如果文档类型不正确, responseXML 的值将会是空的
                    var dom = xhr.responseXML; // 返回是 dom 对象
                    document.getElementById("d1").innerHTML = data;
                }
            }
        }
        // 初始化xhr对象 ,// 建立与服务器的连接
        xhr.open("GET", "/ServletDemo?username=xxx");
        
        // 发送数据
        // 如果是GET方法, 不会发送任何数据, 传递null即可
        xhr.send(null); 
        
        // 如果是Post方法, 如果没有数据作为请求的一部分发送, 也是用null
        // 设置请求消息头, 告知服务器, 发送的正文数据类型
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send("name=xxx&age=xxx");
        // 或 xhr.send({name:"itcast"});

    }
}

XMLHttpRequest 对象方法

方法 描述
abort() 停止当前请求
getAllResponseHeaders() 把http请求的所有响应首部作为键/值对返回
getResponseHeader("headerLabel") 返回指定首部的串值
open("method", "url", "isAsync") 建立对服务器的调用, method可以为 GET POST
send(content) 向服务器发送请求
setRequestHeader("label", "value") 把指定首部设置为所提供的值, 在设置任何首部之前必须先调用open()

XMLHttpRequest 对象属性

属性 描述
onreadystatechange 状态改变的事件触发器(回调函数), 服务器触发
readyState 对象状态(int), 0=未初始化, 1=读取中, 2=已读取, 3=交互中, 4=完成
responseText 服务器进程返回数据的文本版本
responseXML 服务器返回数据兼容DOM的XML的文档对象
status 返回状态码, 404, 200
statusText 状态文本信息

案例校验用户名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<form>
    <input type="text" id="username" name="username" onblur="checkUsername()"/>
    <span id="checkResult"></span>
    <input type="text" name="email"/>
    <input type="submit"/>
</form>
<script type="text/javascript">
function checkUsername(){
     var nameInputElm = document.getElementById("username");
     var xmlHttpReq = createXmlHttpRequest()
     xmlHttpReq.onreadystatechange = function(){
         if(xmlHttpReq.readyState == 4) {
             if(xmlHttpReq.status == 200  || xhr.status == 304) {
                 var result = xmlHttpReq.responseText;
                 document.getElementById("checkResult").innerHTML = result;
             }
         }
     };
     xmlHttpReq.open("POST", "/checkUsername");
     xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
     xmlHttpReq.send({username: nameInputElm.value})
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
// checkUsernameServlet
List names = Array.asList(new String[]{"abcd", "efg", "qwe"});
public void doPost(request, response) {
    response.setContentType("text/html;charset=utf-8");
    request.setCharactorEncoding("utf-8");
    String username = request.getParameter("username");
    
    if(names.contains(username)) {
        response.getWriter().print("用户名已经存在");
    } else {
        response.getWriter().print("用户名不存在存在");
    }
}

JSON

JavaScript Object Notation, 比 xml 更轻巧, 是 JavaScript 的原生格式

1
2
3
4
5
6
public void doGet(req, resp) {
    resp.setContentType("text/json;charset=utf-8");
    PrintWriter out = resp.getWriter();
    String str = "{name:'山东'}";
    out.print(str);
}
1
2
3
4
5
6
7
8
9
var xhr = createXmlHttpRequest();
xhr.onreadystatechange = function() {
    if(xhr.status==200 || xhr.status ) {
       // 返回值是 json 的字符串形式
       var data = xhr.responseText;
       // 把普通的 json 文本转换成 json 数据
       var json = eval("("+ data + ")");
    }
}

JSONlib 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 省, 邮政编码
Province p = new Provice("山东省", 250000);
JSONObject jsonObj = JSONObject.fromObject(p);
jsonObj.toString();   // {"name":"山东省", "zipcode":"250000"}

// 输出数组
Province p1 = new Provice("山东省", 250000);
Province p2 = new Provice("浙江", 320000);
List ps = new ArrayList<Province>();
ps.add(p1);
ps.add(p2);
JSONArray jsonArr = JSONArray.fromObject(p2);
jsonArr.toString() // [{name:**, zipcode:**},{name:**, zipcode:**}]

// 过滤输出
JsonConfig cfg = new JsonConfig();  
cfg.setExcludes(new String[]{"zipcode"}); // 不包含的字段列表
JSONArray jsonArr = JSONArray.fromObject(p2, cfg);
jsonArr.toString() // [{name:**},{name:**}]

FlexJson

flexjson 是一个轻量级的java类库, 序列化 Json

  • 序列化对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    Product p = new Product(1, "冰箱", 200);
    p.setOrders(orders);
    JSONSerializer jsonSerializer = new JSONSerializer();
    // jsonStr:  {class:"zhpooer.Product" , id: 1, name: "冰箱", price: "200"}
    // 不会序列化集合
    String jsonStr = jsonSerializer.serialize(p);
    // 序列化文档
    String jsonStr =jsonSerializer.include("orders").serialize(p);
    // 排除序列化属性
    String jsonStr =jsonSerializer.exclude("name").serialize(p);
    // 使用注解排除属性 @JSON(include=false)
    

服务器返回xml

Xml格式, 不依赖任何语言,, 跨平台第三方通用数据格式

xstream

实现 xml 和 java 之间相互转换

XMl解析方式: DOM, SAX, Stax(pull 解析采用Stax)

导入jar包: xstream,jar xpp3.jar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 将对象转换为 xml
User user = new User();
user.setId(1);
user.setName("");
user.setGender("男");
XStream xStream = new XStream();
// 给User取别名
xStream.alias("user", User.class);
xStream.alias("users", List.class);
String xml = xStream.toXML();

// 解析XML
XStream xStream = new XStream();
xStream.alias("user", User.class);
xStream.alias("users", List.class);
xStream.fromXML(new FileInputStream("user.xml"));

使用XML 注解

1
2
3
4
5
6
7
8
9
10
11
12
// 起别名
@XStreamAlias("User")
public class User{
    @XStreamAsAttribute
    private int id;
    // 不使用
    @XStreamOmitField
    private String gender;
}
XStream xStream = new XStream();
// 是注解生效
xStream.autodetectAnnotations(true);

Tip

1
2
<!-- 不处理链接 -->
<a href="javascript:void(0)">商品数据</a>
文章目录
  1. 1. 同步和异步
  2. 2. AJAX
  3. 3. 与服务器通信
  4. 4. XMLHttpRequest 对象方法
  5. 5. XMLHttpRequest 对象属性
  6. 6. 案例校验用户名
  7. 7. JSON
    1. 7.1. JSONlib 使用
    2. 7.2. FlexJson
  8. 8. 服务器返回xml
    1. 8.1. xstream
    2. 8.2. 使用XML 注解
  9. 9. Tip