STAGE02-DAY19-AJAX
历史回顾
监听器(Listener)
监听器是实现了特殊监听接口的类,功能是用来监听作用域的创建、销毁、值的变化及类与session的关系。
一组:监听创建与销毁ServletContext、reqeust、session 3个
二组:监听值的变化 3个
三组:监听类与session的关系--是否绑定对象(要求对象上实现接口),是否钝化与活化
过滤器(Filter)
过滤器是实现了Filter接口的类,功能是拦截请求。
AJAX
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
Ajax = 异步 JavaScript 和 XML 或者是 HTML(标准通用标记语言的子集)。
Ajax 是一种用于创建快速动态网页的技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
表单数据提交
a连接数据提交
javascript数据提交
以上三种都需要请求后台但是如果想更新数据必须刷新网页,Ajax完美解决了这个问题。
生活中的例子:如点赞,弹幕等局部实时更新的网页都会用到Ajax技术
原生Ajax--纯js写的Ajax
http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_create.asp
原生AJAX需要借助 XMLHttpRequest 对象实现
原生ajax使用步骤:
- 创建一个XMLHttpRequest对象
- 调用open并传递三个参数:请求方式、url、true
- 发送(send)这个请求
- 定义获取返回状态的方法onreadystatechange
- 判断这个状态4为成功
- 从Response响应主体中获取返回的信息。Ajax获取信息只能通过响应来获得,不能直接从作用域中拿值,且这个响应只能响应一次。如果没有Ajax,response响应的时候会直接显示在网页上,当有Ajax的时候,相当于Ajax拦截了这个响应并为自己所用。
错误:
1.print不能用write只能用print,不然会出现乱码
2.获得返回值时需要定义函数xhr.onreadystatechange=function(){},xhr这边是属性,没有括号
3.var value = xhr.responseText也是属性,后面没有括号
4.JS给文本赋值是 .innerText=,jQuery是 .text=
5.原生js脚本中的选择器不要#和. jQuery和css需要使用,不要搞混了,否则没有结果!!
6.servlet中的pw一定要放在else的外面,否则第一个缺失!!!
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>焰灵姬</title> <script type="text/javascript"> function point(){ //1.创建XMLHTTPRequest对象 var xhr = new XMLHttpRequest(); //2.调用xhr的open方法并为其传参 xhr.open("post","MyServlet",true);//第一个参数为发送方法,第二个为URL,第三个为true //3.发送 xhr.send(); //4.定义函数,获得返回值 xhr.onreadystatechange = function(){ //5.判断返回状态是否为4,是的话就是正常的,可以进行赋值操作 if(xhr.readyState == 4){ var value = xhr.responseText; //6.赋值 document.getElementById("sp").innerText = value; } } } </script> </head> <body> <img alt="网速不好图片显示不出来的时候显示,或者鼠标移上去的时候显示" src="pic/1.png" width="70%"><br> 获得点赞次数为:<span id="sp"></span>次!<span></span><br> <input type="button" id="bu" value="点赞" onclick="point()"> </body> </html>
package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/MyServlet") public class MyServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /*首先我们假定一个作用域,服务器级别的,这样除非关闭服务器,否则点赞数会一直存在,符合实际, 专门用来存放点赞数,如果值为null的话说明还未创建,我们就创建这个作用域并赋值为0 */ PrintWriter pw = response.getWriter();//Ajax只能通过响应的方式获取值,其他方式不行 ServletContext context = this.getServletContext(); int num = 1;//初始化变量,这个变量用以记录点赞次数 Object object = context.getAttribute("con"); //判断 if(null == object) { context.setAttribute("con", 1); num=1; }else { num = (int)object;//一开始我们需要判断是不是null,所以不能一开始就转型,判断完成之后我们可以给他转成int了 num++;//每次点赞都+1 context.setAttribute("con", num); System.out.println("点赞次数为:"+num); } pw.print(num);//一定要放到外面,否则打印不到第一个了!!!!!!!!!! } }
jQuery ajax
作为JavaScript一个类库,必然也会有响应的ajax的功能,jQuery认为原生ajax过于复杂,所以进行了一次封装(jQuery的二次封装)。 共定义3种书写ajax的方式。
要求:
先导入jQuery类库。也叫脚本文件。
语法:顺序可以不一致
$.ajax({ url:"", data:{},//书写Jason格式的值 type:"", dataType:"", success:function(){},//书写函数 error:function(){}//,书写函数,注意最后一个没有分号 ; });
解析:
$.ajax:声明使用的jQuery ajax语法结构 $.ajax({.......})
url: 请求的地址
data: 需要发送的数据{} 里面书写json格式的数据 {名字:值,名字:值}
type: 请求类型 get/post
dataType:声明返回数据(响应主体中)的类型/格式
success:执行成功之后调用的方法 等同于 xhr.readyState = 4
error: 执行不等于4 调用的方法。 如果没有错误error可以省略
注意事项:
- 注意不要写错单词。
- ajax严格区分大小写。
- 冒号一定是英文的。
- ajax中书写的每一项结尾都要跟随逗号,除最后一个!!!
- dataType T要大写。
- $.ajax内的选项不区分顺序。
第一种:$.ajax({...})
注意:三种写法中,只有这个括号中是带大括号的。
servlet代码不变,jsp代码如下
注意,function()括号内传参,逗号不要漏掉!!
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ajax的jQuery简写格式1</title> <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script> <script type="text/javascript"> $(function(){//就绪函数 $("#bu").click(function(){//绑定事件 $.ajax({ url:"MyServlet", data:{}, dataType:"text", type:"post", success:function(num){//函数为有参函数,括号里传值,这个值就是我们用pw响应到页面的值 document.getElementById("sp").innerText = num; },//注意逗号不要漏了!!! error:function(){ alert("ajax错误"); } }); }); }); </script> </head> <body> <img alt="网速不好图片显示不出来的时候显示,或者鼠标移上去的时候显示" src="pic/1.png" width="70%"><br> 获得点赞次数为:<span id="sp"></span>次!<span></span><br> <input type="button" id="bu" value="点赞"> </body> </html>
第二种:$.get();
格式为$.get( url, data, success ,dataType ) 顺序固定,但是没有值的时候可以省略不写,否则报错,写的时候直接写值就好不用写标签名,这里只是指定位置。
注意:
1.get()括号后直接跟内容,没有大括号!!!
2.jQuery赋值:$("#id").text(值) 不用等于号,直接在text后括号内给值
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>get方法</title> <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script> <script type="text/javascript"> $(function(){ $("#bu").click(function(){ $.get( "MyServlet", //url //{},//data function(num){//success $("#sp").text(num); }, "text"//dataType ); }); }); </script> </head> <body> <img alt="网速不好图片显示不出来的时候显示,或者鼠标移上去的时候显示" src="pic/1.png" width="70%"><br> 获得点赞次数为:<span id="sp"></span>次!<span></span><br> <input type="button" id="bu" value="点赞"> </body> </html>
第三种:$.post();
post 格式为 $.get( url, data, success ,dataType )
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ajax简化-post</title> <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script> <script type="text/javascript"> $(function(){ $("#bu").click(function(){ $.post( "MyServlet", //{}, 位置不能乱,但是值没有可以省略不写 function(num){ $("#sp").text(num); }, "text" ); }); }); </script> </head> <body> <img alt="网速不好图片显示不出来的时候显示,或者鼠标移上去的时候显示" src="pic/1.png" width="70%"><br> 获得点赞次数为:<span id="sp"></span>次!<span></span><br> <input type="button" id="bu" value="点赞"> </body> </html>
AJAX可以返回的数据类型
XML:早期AJAX都用XML传输数据(被JSON取代)
text:文本格式,字符串格式(所有数据都能用这种格式接收)
HTML:可以直接返回HTML代码
script:脚本代码
JSON:当今最流行的数据回交互方式
JSONP:也是JSON格式,但是支持跨域访问。
JSON
错误的地方:注意 返回值类型 "json" 一定要写在$.get(); $.post();的括号里面,否则不生效,默认的是text,会直接当成字符串输出,写的时候为了防止犯错,在写完get/post 后直接在括号后加 ; 以区分。
JSON是一种数据的格式,本质就是一个特殊格式的字符串。 JSON格式的数据也可以直接使用text去接收。
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
使用AJAX的时候所有JSON返回类型的数据,只要格式正确默认都已经将返回的字符串转化成了对象。可以直接操作这个对象。只要是对象就可以 . 只要是数组就可以遍历
第一种格式:数组格式
[2,3,4,5,6]
首先我们测试以text格式输出:得到一个字符串,只能进行字符串相关操作,比如取0下标的值,返回的会是 "[" 而不是2
下面我们测试以json格式输出:得到一个数组对象,可以进行根据下标取值等操作。
第二种格式:键值对格式(对象格式),常规的JSON格式
{"name":"张三","age":49}
第三种格式:混合模式,对象的数组
json中的遍历:for(var i in obj){ ...... }
[{"name":"张三","age":49},{"name":"李四","age":3}]
第四种格式:可以支持直接返回boolean值
JSON转化工具
jsonlib 比较常见一种转化工具,通用但是功能不是特别强大
fastjson 这个工具功能很强大,但是在Hibernate框架中转化会出现异常。解决不彻底(死循环)。
jackson 我们一般用这种工具。是一个将对象、集合、数据等各种数据格式转化为JSON字符串的一个工具。
使用的时候需要导三个包。
测试一:数组类型不需要转化直接打印回去即可。
测试二:转化对象
方法:
- 定义一个对象映射器 ObjectMapper mapper = new ObjectMapper();
- 将对象传入writeValueAsString(obj)方法中,得到字符串,以便json传递 String values1 = mapper.writeValueAsString(s1);
测试三:转化集合
方法基本和上面一样
AJAX进阶之Error回调函数
只有程序在发生错误的才会执行error回调,如果程序没问题,是不执行。
error回调函数中有三个参数
XMLHttpRequest : 原生Ajax的核心对象| 在jQuery1.5之后简写jqXHR
textState :返回异常的文本标识
errorThrown :返回ajax抛出异常信息
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/MyJackson") public class MyJackson extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter pw = response.getWriter(); pw.print("hhh"); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script> <script type="text/javascript"> $(function(){ $("#bu").click(function(){ $.ajax({ url:"",//第三个报错的原因,加上Servlet地址即可,最后行数是0代表没错 data:{}, dataType:"json",//第二个出错的原因,解析错误,如果改成text即可消除错误 type:"post", success:function(){ alert("成功"); }, error:function(XMLHttpRequest ,textState ,errorThrown ){ alert("XMLHttpRequest"+XMLHttpRequest); alert("textState"+textState); alert("errorThrown"+errorThrown); } }); }); }); </script> </head> <body> <input type="button" id="bu" value="json"> </body> </html>
XMLHttpRequest
1.5之后使用jqXHR 代替
这个参数对象中有两个方法
第一个获取当前执行的步骤状态代码
jqXHR.readyState
状态码含义:
0 未初始化成功
1 ajax正在发送请求
2 ajax已经请求至后台
3 解析返回的数据
4 数据已经成功返回。
status 直接返回响应状态码
200 (成功)
404
500....
textState
返回异常的文本状态
error:服务器内部发生错误(伴随500产生) 说直白点就是Java类错了
parseerror 解析异常。(检查ajax返回类型)
timeout:请求超时、响应超时。
null : 这个后台的错误太奇葩为定义这个返回文本状态
errorThrown
返回ajax部分执行的异常
只有ajax部分的异常才能返回,Java类中的异常是不能返回的。