第三部分:AJAX 异步 JavaScript和 XML ---- 不是一种新的编程语言
AJAX = DHTML + XHR (在HTML、CSS、JS 基础上 添加 XMLHttpRequest )
传统web方式:浏览器直接将请求发送给服务器,提交请求后,客户端需要等待响应 (用户无法进行任何操作),当响应回来后,整个页面都需要刷新
Ajax web方式:浏览器将请求提交 Ajax 引擎(XMLHttpRequest), 由引擎负责将请求提交给服务器,服务器产生响应也会发回给引擎,引擎更新页面,与传统方式区别是,当浏览器提交请求给Ajax 引擎后,浏览器可以继续操作,当响应回来后,局部刷新页面 ------- 用户的感受非常好
(预加载和懒加载 )
预加载:访问百度,主页非常简洁,在点击搜索前,将搜索结果页面必要数据,通过Ajax加载 ,点击搜索,因为部分搜索结果页面的数据已经加载,结果页面打开非常快
访问商品信息页面,浏览器上面商品信息时,通过Ajax 将下面评论提前加载,用户查看评论时,显示非常快 。
懒加载:访问网易、新浪,主页中信息量非常大 --- 先加载看到部分内容,其它没有第一时间看到内容,通过点击时再进行加载或者使用预加载
编写第一个Ajax程序 (必须存在服务器端)---- 创建Dynamic web project ajaxweb
1.创建XMLHttpRequest对象
属性:onreadystatechange 回调函数、responseText/responseXML 结果数据、status 状态码、readyState Ajax访问状态0 = 未初始化 1 = 正在加载
2 = 已加载3 = 交互中4 = 完成
方法:open(method,url, asynch) :建立对服务器的调用、send(content) :向服务器发送请求
var xmlHttp;
function createXMLHttpRequest() {
try {
xmlHttp = new XMLHttpRequest();
} catch (tryMS) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (otherMS) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xmlHttp = null;
// 这里可以报一个错误,无法获得 XMLHttpRequest对象
}
}
}
return xmlHttp;
}
2.将状态触发器绑定到一个函数
xmlHttp.onreadystatechange = callback;
3.使用open方法建立与服务器的连接
open("GET",url?拼接参数); ----- send参数可以为null
open("POST",url) ----- 这时参数要通过send来发送
4.向服务器端发送数据
1)GET方式提交
数据在URL上
xmlHttp.send(null);
2)POST方式提交
xmlHttp.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded");// 必须写
xmlHttp.send("name=xxx&pwd=xxx");
5.在回调函数中对返回数据进行处理
xmlHttp.readyState == 4
xmlHttp.status == 200
通过 responseText/responseXML 获取结果数据
案例一:采用Ajax校验用户名是否合法(是否存在)
思考:服务器如何将用户名校验结果 通知客户端 ???
<script type="text/javascript">
// Ajax编程第一步 ,创建 XMLHttpRequest
var xmlHttp;
function createXMLHttpRequest() {
try {
xmlHttp = new XMLHttpRequest();
} catch (tryMS) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (otherMS) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xmlHttp = null;
// 这里可以报一个错误,无法获得 XMLHttpRequest对象
}
}
}
return xmlHttp;
}
// 采用异步方式 访问服务器,获取用户名是否有效信息
function validateUsername(){
// 第一步
createXMLHttpRequest();
// 第二步 绑定状态触发器 到 函数上
xmlHttp.onreadystatechange = callback;// 会自动调用 callback
// 第三步 建立与服务器目标资源连接
var username = document.getElementById("username").value;
xmlHttp.open("GET","/ajaxweb/checkUsername?username="+username);
// 第四步 发送请求参数
xmlHttp.send(null);
}
// 第五步 回调函数的编写
function callback(){
// 响应完成后 才对数据进行处理
if(xmlHttp.readyState == 4){
if(xmlHttp.status == 200) {// 判断响应状态码为200
var data = xmlHttp.responseText ;
// alert(data);
// 接收的是一个HTML代码片段,将片段直接通过 innerHTML 插入指定位置
document.getElementById("showmsg").innerHTML = data;
}
}
}
</script>
</head>
<body>
<!-- 采用Ajax 校验用户名是否已经存在 -->
<h1>注册表单</h1>
<form>
用户名 <input type="text" name="username" id="username" οnblur="validateUsername();"/><span id="showmsg"></span><br/>
密码 <input type="password" name="password" id="password" /><br/>
<input type="submit" value="注册" />
</form>
</body>
</html>
常用的服务器返回数据格式
1)HTML片段
2)JSON格式的数据
3)XML格式的数据
HTML代码片段返回值,直接通过innerHTML 插入指定位置显示
案例二:table的数据抓取
product.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest() {
try {
xmlHttp = new XMLHttpRequest();
} catch (tryMS) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (otherMS) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xmlHttp = null;
// 这里可以报一个错误,无法获得 XMLHttpRequest对象
}
}
}
return xmlHttp;
}
// 显示商品信息
function showProductInfo(){
// AJAX 编程
createXMLHttpRequest();
xmlHttp.onreadystatechange = callback;
xmlHttp.open("GET","/ajaxweb/listproducts");
xmlHttp.send(null);
}
function callback(){
if(xmlHttp.readyState == 4){
if(xmlHttp.status == 200){
var data = xmlHttp.responseText;// 回写table 数据
document.getElementById("showinfo").innerHTML = data;
}
}
}
</script>
</head>
<body>
<a href="javascript:showProductInfo();">显示商品信息</a>
<hr/>
<div id="showinfo">还没有选择数据</div>
</body>
</html>
/**
* 显示商品信息
*/
public class ListproductsServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 伪造商品数据
List<Product> products = new ArrayList<Product>();
Product p1 = new Product();
p1.setName("冰箱");
p1.setPrice(2000);
Product p2 = new Product();
p2.setName("洗衣机");
p2.setPrice(3000);
products.add(p1);
products.add(p2);
// 返回HTML ,Servlet生成HTML 不方便 --- 使用JSP
request.setAttribute("products", products);
request.getRequestDispatcher("/list.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
list.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!-- 回写 HTML片段 -->
<table border="1">
<tr>
<th>商品名称</th>
<th>商品价格</th>
</tr>
<c:forEach var="p" items="${products }">
<tr>
<td>${p.name }</td>
<td>${p.price }</td>
</tr>
</c:forEach>
</table>
===================================================================================================================
第四部分:JSON和 XML的数据生成
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。
官网 http://www.json.org/
1、JSON存在两种结构
第一种 {key:value,key:value,... key:value} --- 相当于map
第二种 [value,value,...value] ---- 相当于数组
2、为什么要学JSON ? AJAX 需要从服务器向客户端 返回JSON格式的数据
服务器需要将数据转换为JSON 格式 ------ Json-lib
下载jar包 ---- 导入6个jar包到工程
1) 使用JSONArray.fromObject 将 数组、集合对象 转换为JSON 格式
2) 使用JSONObject.fromObject 将javabean 、map 转换为JSON格式
** 使用JsonConfig 配置不需要转换的属性
将json格式转换为对象
JSONObject jsonObject = JSONObject.fromObject(json格式string);
JsonObject.toBean(jsonObject,Product.class);
@Test
public void demo3() {
// 使用JsonConfig 配置不需要转换到json 格式的属性
Product product = new Product();
product.setName("冰箱");
product.setPrice(3000);
Product product2 = new Product();
product2.setName("洗衣机");
product2.setPrice(2000);
List<Product> list = new ArrayList<Product>();
list.add(product);
list.add(product2);
// 定义JSONConfig用于过滤不需要过滤可以不写
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[] { "price" });
JSONArray jsonArray = JSONArray.fromObject(list, jsonConfig);
System.out.println(jsonArray);
}
@Test
public void demo1() {
// 转换对象 到json格式
Product product = new Product();
product.setName("冰箱");
product.setPrice(3000);
JSONObject jsonObject = JSONObject.fromObject(product);
System.out.println(jsonObject);
}
@Test
public void demo2() {
// 将List集合转换 json格式
Product product = new Product();
product.setName("冰箱");
product.setPrice(3000);
Product product2 = new Product();
product2.setName("洗衣机");
product2.setPrice(2000);
List<Product> list = new ArrayList<Product>();
list.add(product);
list.add(product2);
JSONArray jsonArray = JSONArray.fromObject(list);
System.out.println(jsonArray);
}
3、Xstream将java对象转换 xml文档
转换 java - xml 不需要导入 xpp3_min-1.1.4c
转换 xml - java 需要导入 xpp3_min-1.1.4c
toXML 转换 java对象到 XML
通过Xstream的注解 配置转换过程
Xstream Annotation
@XStreamAlias(别名) 对类和变量设置别名
@XStreamAsAttribute 设置变量生成属性
@XStreamOmitField 设置变量 不生成到XML
@XStreamImplicit(itemFieldName = “hobbies”) 设置集合类型变量 别名
eg:
@XStreamAlias("product")
// 别名
public class Product {
// 作为属性
@XStreamAsAttribute
private String name;
// 不想price到xml中
@XStreamOmitField
private double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
在Xstream生成XML时使用注解
xStream.autodetectAnnotations(true);//使用注解必须写这句
@Test
public void demo3() {
// 注解 进行转换
Product product = new Product();
product.setName("冰箱");
product.setPrice(3000);
Product product2 = new Product();
product2.setName("洗衣机");
product2.setPrice(2000);
List<Product> list = new ArrayList<Product>();
list.add(product);
list.add(product2);
XStream xStream = new XStream();
xStream.autodetectAnnotations(true);
System.out.println(xStream.toXML(list));
}
@Test
public void demo1() {
// 转换java对象 到xml
Product product = new Product();
product.setName("冰箱");
product.setPrice(3000);
XStream xStream = new XStream();
//为product.class起个别名
xStream.alias("product", Product.class);
System.out.println(xStream.toXML(product));
}
@Test
public void demo2() {
// 转换 list到xml
Product product = new Product();
product.setName("冰箱");
product.setPrice(3000);
Product product2 = new Product();
product2.setName("洗衣机");
product2.setPrice(2000);
List<Product> list = new ArrayList<Product>();
list.add(product);
list.add(product2);
XStream xStream = new XStream();
xStream.alias("product", Product.class);
xStream.alias("products", List.class);
System.out.println(xStream.toXML(list));
}
============================================================================================
Ajax返回客户端三种数据格式 HTML JSON XML ------ 最优是JSON (数据最少)
如果服务器返回客户端JSON 字符串,客户端必须通过 eval() 将json字符串 转换为 JSON对象
* 语法 : eval("("+json+")");
例如:
var json = "{'name':'zhangsan','age':18}";
// 需要将json字符串 转换 js对象
var jsonObj = eval("("+json+")");
alert(jsonObj.name);
alert(jsonObj.age);
重做AJAX案例二 : table数据抓取 ,返回json格式数据
<script type="text/javascript" src="jquery-1.8.2.min.js"></script>
<script type="text/javascript">
$(function(){
})
var xmlHttp;
function createXMLHttpRequest(){
try {
xmlHttp = new XMLHttpRequest();
}
catch (tryMS) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (otherMS) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (failed) {
xmlHttp = null;
// 这里可以报一个错误,无法获得 XMLHttpRequest对象
}
}
}
return xmlHttp;
}
function listproduct(){
createXMLHttpRequest();
xmlHttp.onreadystatechange=list;
xmlHttp.open("GET","/ajax01/AddProduct");
xmlHttp.send(null);
}
function list(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
var data=xmlHttp.responseText;
var product=eval('('+data+')')
var buf=""
buf+="<table border='1'><tr><th>商品名称</th><th>商品价格</th></tr>"
for(var i=0;i<product.length;i++){
buf+="<tr><td>"+product[i].name+"</td><td>"+product[i].price+"</td></tr>"
}
buf+="</table>"
$("#div0").html(buf);
}
}
}
</script>
</head>
<body>
<a href="javascript:listproduct();">显示商品</a>
<div id='div0'>
</div>
</body>
</html>
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<Product> list = new ArrayList<Product>();
Product product = new Product();
product.setName("冰箱");
product.setPrice(3000);
Product product2 = new Product();
product2.setName("洗衣机");
product2.setPrice(2000);
list.add(product);
list.add(product2);
JSONArray json = JSONArray.fromObject(list);
response.setContentType("text/plain;charset=utf-8");
response.getWriter().print(json);
}
AJAX案例三:省市 select 联动 ---- 服务器回送XML 片段
xmlHttp.responseXML 接收返回 xml ,直接得到dom 对象