Ajax
-
asynchronous(异步) javascript and xml,主要作用是发送异步请求
-
传统请求 - 同步请求
- 发送请求方式:地址栏请求,HTML页面超链接请求,HTML页面表单请求,通过location.href发送请求
- 同步请求存在的缺陷
- 上一次请求没有响应回来之前,无法继续发送下一次请求,属于阻塞式请求
- 同步请求响应的是一整张页面,会丢弃之前的页面,浪费资源,用户体验差
Ajax发送异步请求
- 发送异步请求的核心对象:js中的一个内置对象 xhr
- 创建xhr对象:
- IE7版本以前:xhr = new ActiveXObject(“Microsoft.xmlhttp”);
- IE7浏览器及其以后的版本和非IE浏览器:xhr = new XMLHttpRequest();
- 创建xhr对象:
<--
处理ajax请求:
响应的结果是一小段字符串信息,不做跳转,即返回null -->
//发送get请求
<script type="text/javascript">
function sendAjaxReq() {
//创建xhr对象
let xhr;
if (window.ActiveXObject) {
xhr = new ActiveXObject('Microsoft.xmlhttp');
} else {
xhr = new XMLHttpRequest();
}
//明确请求目标和请求方式
xhr.open('get', '${pageContext.request.contextPath }/ajaxAction');
//注册一个监听响应的事件
xhr.onreadystatechange = function () {
/*
* xhr.readyState == 4 代表响应已经完全解析完毕,可以使用响应结果
* 0 代表xhr对象已经创建,但请求还未初始化
* 1 开始发送请求,但还没有响应结果
* 2 开始响应结果,但还没有开始解析
* 3 开始解析响应结果,但还没有解析完
* 4 响应结果并完全解析,可以使用
* xhr.status == 200 代表本次请求但状态 200代表成功
* */
if (xhr.readyState == 4 && xhr.status == 200) {
let respTxt = xhr.responseText;
console.log('响应结果:', respTxt);
//通过DOM编程把响应结果添加到页面
let sp = document.getElementById('sp');
sp.innerText = respTxt;
}
};
//发送请求
xhr.send();
}
//发送post请求
function sendAjaxReqPost() {
//创建xhr对象
let xhr;
if (window.ActiveXObject) {
xhr = new ActiveXObject('Microsoft.xmlhttp');
} else {
xhr = new XMLHttpRequest();
}
//设置请求目标和请求方式
xhr.open('post', '${pageContext.request.contextPath }/ajaxAction');
//设置请求头类型,模拟表单发送post请求
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
//注册监听响应事件
xhr.onreadystatechange = function () {
//获取响应结果
if (xhr.readyState == 4 && xhr.status == 200) {
let respTxt = xhr.responseText;
console.log('响应结果:', respTxt);
}
}
//发送请求
xhr.send('username=Mo');
}
</script>
-
异步请求特点
- 响应的是一小段字符串信息(服务器端不做资源的跳转),从浏览器页面来讲属于网页的局部内容
- 属于非阻塞式请求,用户不需要等待上一次请求响应,便可以继续发送其他的请求
- 异步请求可以让用户的操作更加自由和连续,用户的体验更好
-
模拟JSON传递数据
public String suggestSearch() throws IOException { if(StringUtils.isNotEmpty(name)){ List<City> cityList = cityService.findByLikeName(name); StringBuffer sbu = new StringBuffer(); for(int i=0;i<cityList.size();i++){ sbu.append(cityList.get(i).getName()); if(i<cityList.size()-1){ sbu.append(":"); } } String cityStr = sbu.toString(); //响应结果 HttpServletResponse response = ServletActionContext.getResponse(); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.write(cityStr); out.flush(); } return null; } xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { let result = xhr.responseText; let data = result.split(":"); console.log(data); for (var i = 0; i < data.length; i++) { //验证数据源中的数据data[i]是否和用户输入的name相关 if (data[i].indexOf(name) >= 0) { $("tbody").append("<tr><td>" + data[i] + "</td></tr>"); } } } }
JSON
-
在实际的企业级应用开发中,会涉及到不同的系统平台之间的相互调用,需要不同系统平台间的数据的传递交互,为了更好的进行数据的通信和交互,业内指定了统一的数据通信载体,即JSON字符串进行通信
-
跨平台通信:不同的编程语言或不同的应用系统之间进行数据的传递和交互。
- 跨平台通信的数据载体:
- JSON格式字符串:本质为字符串;基本格式为=={“key”:“value”,…}==
- XML文件:主要以标签的方式描述数据,相比于JSON字符串的解析成本较高
- 跨平台通信的数据载体:
-
JavaScript Object Notation,是一种轻量级的数据交换格式。易于人阅读和编写,也易于机器解析和生成
-
JSON采用完全独立于语言的文本格式,而且很多语言都提供了对JSON的支持,这就使得JSON成为理想的数据交换格式
-
轻量级指与xml作对比
-
数据交换指的是客户端和服务器之间业务数据的传递格式
-
JSON是由键值对组成,并且由花括号包围{}。每个键由引号引起来,键和值之间使用冒号进行分割,多组键值对之间使用逗号进行分隔
-
XML数据格式:通过标签,描述性较强,但解析成本高
-
JSON数据格式:
- 普通JSON字符串:{“name”:“value”,…}
- 数组类型:[“val1”,“val2”]
- 复杂类型的:
{“name”:{n:v,n,v},“name”:[“v1”,“v2”] }
[{“name”:“value”},{“name”:“value”}]
-
JSON字符串的转换
Java中的对象 JSON字符串 class User{
private String username;
private String password;
};
new User(“mo”,“LoveMe”);{“username”:“mo”,“password”:“LoveMe”} List users = new ArrayList();
users.add(new User(“mo”,“LoveMe”));
users.add(new User(“hang”,“123”));[{“username”:“mo”,“password”:“LoveMe”},
{“username”:“hang”,“password”:“123”}]Map<String,String> maps…;
maps.put(“username”,“mo”);
maps.put(“password”,"LoveMe);
Map<String,User> maps…;
maps.put(“u1”,new User(“A”,“123”));
maps.put(“u2”,new User(“B”,“123”));{“username”:“mo”,“password”:“LoveMe”}
{“u1”:{“username”:“A”,“password”:“123”},
“u2”:{“username":“B”,“password”:“123”}
}String[] ss = {“A”,“B”,“C”}; [“A”,“B”,“C”] -
json的两个常用方法
-
json的存在有两种形式
- 对象形式,称为json对象,通常操作json中的数据的时候使用
- 字符串的形式,称为json字符串,通常在客户端和服务器之间进行数据交换的时候使用
-
JSON.stringify() 把json对象转换成json字符串
-
JSON.parse() 把json字符串转换成json对象
//json对象转字符串 var jsonObjString = JSON.stringify(jsonobj); //类似与java中对象的tostring alert(jsonObjString); //json字符串转json对象 var jsonObj2 = JSON.parse(jsonObjString); alert(jsonObj2);
-
-
Gson工具的使用 – 需要引入依赖
-
javaBean和json的互转
-
toJson():把java对象转换成为json字符串
-
fromJson():把json字符转换回Java对象,第一个参数是json字符串,第二个参数是转换回去的Java对象类型
-
基本使用
Gson gson = new Gson(); String jsonUser = gson.toJson(new User("mo", "LoveMe")); List<User> users = new ArrayList<>(); users.add(new User("mo","LoveMe")); users.add(new User("yuan","LoveMe")); Gson gson = new Gson(); String jsonList = gson.toJson(users); Map<String,User> users= new HashMap<String,User>(); users.put("k1",new User("mo","LoveMe")); users.put("k3",new User("yuan","LoveMe")); Gson gson = new Gson(); String jsonMap = gson.toJson(users);
-
注解
//在实体类属性加注解,自定义JSON转换的key的名字 @SerializedName("name") private String username ;
-
日期类型转换
// 创建一个Gson的建造者 GsonBuilder builder = new GsonBuilder(); //自定义日期格式 builder.setDateFormat("yyyy-MM-dd HH:mm:ss"); Gson gson = builder.create(); String jsonUser = gson.toJson(user);
-
JSON转换对象回环
Person person = new Person(); person.setId(1); person.setName("mo"); Address addr = new Address(); addr.setId(1); addr.setStreet("北京"); addr.setPerson(person); person.setAddress(addr);
-
自定义排除策略
//实现自定义排除策略的接口 public class CustomStrategy implements ExclusionStrategy { //根据属性判断是够跳过转换 @Override public boolean shouldSkipField(FieldAttributes field) { System.out.println(field.getName()); //根据实体类属性名判断是否跳过转换 if("person".equals(field.getName())){ //不需要转换 return true; } return false; } //根据类的类型判断是否跳过转换,使用一个方法即可 @Override public boolean shouldSkipClass(Class<?> aClass) { System.out.println(aClass); if(Address.class.equals(aClass)){ return true; } return false; } } //类中使用 //创建Gson的建造者 GsonBuilder builder = new GsonBuilder(); //设置自定义排除策略的实现类 builder.setExclusionStrategies(new CustomStrategy()); //接口回调 Gson gson = builder.create();
-
接口回调掩饰
public interface IA { String hello(); } public class MyClass { public void printHelloXxx(IA ia){ String hello = ia.hello(); System.out.println(hello); } } public class TestMyClass { public static void main(String[] args) { MyClass myClass = new MyClass(); myClass.printHelloXxx(new IA() { //匿名内部类实现接口 @Override public String hello() { return "helloWorld"; } }); } }
-
List 和 json互转
//泛型指定为想要转换的类型 public class PersonListType extends TypeToken<ArrayList<Person>> { } //List和json的互转 @Test public void test2() { ArrayList<Person> personList = new ArrayList<>(); personList.add(new Person(1, "hang")); personList.add(new Person(2, "yuan")); //创建Gson对象实例 Gson gson = new Gson(); // 把list转换为json字符串 String PersonListJsonString = gson.toJson(personList); System.out.println(personList); //json字符串转换成list //List<Person> list = gson.fromJson(PersonListJsonString, new PersonListType().getType()); //使用匿名内部类实现 List<Person> list = gson.fromJson(PersonListJsonString,new TypeToken<ArrayList<Person>>(){}.getType()); System.out.println(list); System.out.println(list.get(0)); }
-
map和json的互转
//泛型指定为想要转换的类型 public class PersonMapType extends TypeToken<HashMap<Integer, Person>> { } //map和json的互转 @Test public void test3(){ Map<Integer,Person> personMap = new HashMap<>(); personMap.put(1,new Person(1,"hang")); personMap.put(2,new Person(2,"yuan")); //创建Gson对象实例 Gson gson = new Gson(); //把map集合转换成json字符串 String personMapJsonString = gson.toJson(personMap); System.out.println(personMapJsonString); //json字符串转换成map //Map<Integer,Person> perMap = gson.fromJson(personMapJsonString, new PersonMapType().getType()); //使用匿名内部类,可以简化代码,同时不需要再新写一个类继承TypeToken Map<Integer,Person> perMap = gson.fromJson(personMapJsonString, new TypeToken<HashMap<Integer, Person>>() { }.getType()); System.out.println(perMap); System.out.println(perMap.get(1)); }
-
-
-
JS中将json字符串转换成js对象:JSON.parse(jsonStr);
使用jQuery简化ajax开发
-
. g e t 方 法 和 .get方法和 .get方法和.post:底层封装的ajax
url:待载入页面的URL地址
data:待发送Key / value参数
callback:载入成功时回调函数
type:返回内容格式,xml,html,script,json,text,_default -
发送get请求
$(function(){ $('#btnGet').click(function(){ // 发送ajax请求 //参数1:请求地址 //参数2:传递的数据 //参数3:响应的回调函数 //参数4:指定jquery自动将响应的json字符串转成js对象 $.get('${pageContext.request.contextPath }/city/suggestSearchJson','name=北',function(result){ console.log(result); },'json'); }); })
-
发送post请求
//参数含义等同get $('#btnPost').click(function(){ $.post('${pageContext.request.contextPath }/city/suggestSearchJson','name=北',function(result){ console.log(result); },'json'); });
-
通用方式:$.ajax方法
url:请求的地址
type:请求的类型,GET或POST
data:表示发送给服务器的数据
格式有两种:name=value&name=value ;{key:value}
success:请求成功后,响应的回调函数
dataType:响应的数据类型,常用的数据类型有text纯文本、xml数据、json对象$('#btnAjax').click(function(){ $.ajax({ url:'${pageContext.request.contextPath }/city/suggestSearchJson', //请求路径 type:'get', //请求方式 data:'name=河南', //发送的数据 dataType:'json', //声明响应的数据格式为json,自动转换成js对象 success:function(result){ //响应成功的回调函数 console.log("ajax请求响应",result); }, error:function(){ //响应错误的时候执行 alert('Error!!!'); } }); });
-
使用jQuery交表单数据:先获取到表单对象,然后通过serialize方法把表单数据进行处理
$(function(){ $('#ajaxSubmit').click(function(){ console.log($('#fom').serialize()); $.ajax({ url:'${pageContext.request.contextPath }/city/paramAction', type:'get', data:$('#fom').serialize(), success:function(result){ console.log(result) } }); }); }); <form id="fom"> username:<input type="text" name="username"><br /> password:<input type="password" name="password"><br /> <button type="button" id="ajaxSubmit">提交</button> </form>
-
三级联动
<script type="text/javascript"> $(function(){ //初始化省下拉列表 $.get('/ajax_day2/p/findCity',function(data){ //console.log(data); for(let i=0;i<data.length;i++){ $('#province').append($('<option value="'+data[i].id+'">'+data[i].name+'</option>')); } //手动触发change事件 $('#province').change(); },'json'); //初始化市 $('#province').change(function(){ //清空历史记录 $('#city').empty(); $.get('/ajax_day2/p/findCity','parentId='+$(this).val(),function(data){ for(let i=0;i<data.length;i++){ $('#city').append($('<option value="'+data[i].id+'">'+data[i].name+'</option>')); } //手动触发change事件 $('#city').change(); },'json'); }); //初始化县 $('#city').change(function(){ //清空历史记录 $('#country').empty(); $.get('/ajax_day2/p/findCity','parentId='+$(this).val(),function(data){ for(let i=0;i<data.length;i++){ $('#country').append($('<option value="'+data[i].id+'">'+data[i].name+'</option>')); } },'json'); }); }); </script> <body> 省:<select id="province"></select> 市:<select id="city"></select> 县:<select id="country"></select> </body>