Ajax,jQuery,动态代理初步


Ajax

全局刷新和局部刷新

全局刷新:

整个浏览器被新的数据覆盖。 在网络中传输大量的数据。 浏览器需要加载,渲染页面。

局部刷新:

在浏览器器的内部,发起请求,获取数据,改变页面中的部分内容。其余的页面无需加载和渲染。 网络中数据传输量少, 给用户的感受好。

ajax是用来做局部刷新的。局部刷新使用的核心对象是 异步对象(XMLHttpRequest)
这个异步对象是存在浏览器内存中的 ,使用javascript语法创建和使用XMLHttpRequest对象。

ajax:

Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

Asynchronous: 异步的意思。
JavaScript:javascript脚本,在浏览器中执行。
xml : 是一种数据格式。

ajax是一种做局部刷新的新方法(2003左右),不是一种语言。 ajax包含的技术主要有javascript,
dom,css, xml等等。核心是javascript 和 xml 。

  • javascript:负责创建异步对象, 发送请求, 更新页面的dom对象。 ajax请求需要服务器端的数据。
  • xml: 网络中的传输的数据格式。 使用json替换了xml 。

ajax中使用XMLHttpRequest对象

  1. 创建异步对象 var xmlHttp = new XMLHttpRequest();

  2. 给异步对象绑定事件。onreadystatechange :当异步对象发起请求,获取了数据都会触发这个事件。这个事件需要指定一个函数, 在函数中处理状态的变化。

    1
    2
    3
    4
    btn.onclick = fun1()
    function fun1(){
    alert("按钮单击");
    }

    例如:

    1
    2
    3
    4
    5
    6
    7
    8
    xmlHttp.onreadystatechange= function(){
    处理请求的状态变化。
    if(xmlHttp.readyState == 4 && xmlHttp.status== 200 ){
    //可以处理服务器端的数据,更新当前页面
    var data = xmlHttp.responseText;
    document.getElementById("name").value= data;
    }
    }

    异步对象的属性 readyState 表示异步对象请求的状态变化

    0:创建异步对象时, new XMLHttpRequest();
    1: 初始异步请求对象, xmlHttp.open()
    2:发送请求, xmlHttp.send()
    3: 从服务器端获取了数据,此时3, 注意3是异步对象内部使用, 获取了原始的数据。
    4:异步对象把接收的数据处理完成后。 此时开发人员在4的时候处理数据。
    在4的时候,开发人员做什么 ? 更新当前页面。

异步对象的status属性,表示网络请求的状况的,200,404,500, 需要当status==200
时,表示网络请求成功。

初始异步请求对象

异步的方法open().

1
xmlHttp.open(请求方式get|post, "服务器端的访问地址", 同步|异步请求(默认是true,异步请求))

例如:

1
xmlHttp.open("get", "loginServlet?name=zs&pwd=123",true);

使用异步对象发送请求

1
xmlHttp.send()

获取服务器端返回的数据, 使用异步对象的属性 responseText .
使用例子:xmlHttp.responseText

回调:当请求的状态变化时,异步对象会自动调用onreadystatechange事件对应的函数。

访问地址: 使用get方式传递参数
http://localhost:8080/course_myajax/bmiPrint?name=李四&w=82&h=1.8

使用json

ajax发起请求——-servlet(返回的一个json格式的字符串 :

{ name:”河北”, jiancheng:”冀”,”shenghui”:”石家庄”})

json分类:

  1. json对象 ,JSONObject ,这种对象的格式为:名称:值, 也可以看做是 key:value 格式。

    1. json数组, JSONArray, 基本格式

      [{ name:”河北”, jiancheng:”冀”,”shenghui”:”石家庄”} ,

      { name:”山西”, jiancheng:”晋”,”shenghui”:”太原”} ]

为什么要使用json :

  1. json格式好理解
  2. json格式数据在多种语言中,比较容易处理。 使用java, javascript读写json格式的数据比较容易。
  3. json格式数据他占用的空间下,在网络中传输快, 用户的体验好。

处理json的工具库:

gson(google); fastjson(阿里),jackson, json-lib

在js中的,可以把json格式的字符串,转为json对象, json中的key,就是json对象的属性名。

Ajax

jQuery

  1. jQuery是js库,
    库:相当于java的工具类, jQuery是存放js代码的地方, 放的用js代码写的function。

dom对象和jquery对象

dom对象

使用javascript的语法创建的对象叫做dom对象, 也就是js对象。
var obj= document.getElementById(“txt1”); obj是dom对象,也叫做js对象。
obj.value;

jquery对象

使用jquery语法表示对象叫做jquery对象, 注意:jquery表示的对象都是数组。
例如 var jobj = $(“#txt1”) , jobj就是使用jquery语法表示的对象。 也就是jquery对象。 它是一个数组。现在数组中就一个值。

dom对象与jquery对象相互转换

  • dom对象可以转为jquery , 语法: $(dom对象)
  • jquery对象也可以转为dom对象, 语法: 从数组中获取第一个对象, 第一个对象就是dom对象, 使用[0]或者get(0)。

为什么要进行dom和jquery的转换:目的是使用不同对象的方法。

选择器:

一个字符串, 用来定位dom对象。然后通过jquery的函数操作dom对象

常用的选择器:

  1. id选择器, 语法: $(“#dom对象的id值”)
    通过dom对象的id定位dom对象的。 通过id找对象, id在当前页面中是唯一值。
  2. class选择器, 语法: $(“.class样式名)
    class表示css中的样式, 使用样式的名称定位dom对象的。
  3. 标签选择器, 语法: $(“标签名称”)
    使用标签名称定位dom对象的
  1. 表单选择器,
    使用input标签的type属性值,定位dom对象的方式。
    语法: $(“:type属性值”)
    例如: $(“:text”) ,选择的是所有的单行文本框,$(“:button”) ,选择的是所有的按钮。

过滤器:

在定位了dom对象后,根据一些条件筛选dom对象。
过滤器是一个字符串,用来筛选dom对象。过滤器不能单独使用, 必须和选择器一起使用。

1
2
3
4
5
1)$("选择器:first") : 第一个dom对象
2)$("选择器:last"): 数组中的最后一个dom对象
3)$("选择器:eq(数组的下标)") :获取指定下标的dom对象
4)$("选择器:lt(下标)") : 获取小于下标的所有dom对象
5)$("选择器:gt(下标)") : 获取大于下标的所有dom对象

表单属性过滤器: 根据表单中dom对象的状态情况,定位dom对象。
启用状态, enabled ,
不可用状态 disabled
选择状态 checked , 例如radio, checkbox

each语法

可以对 数组, json ,dom数组循环处理。 数组, json中的每个成员都会调用一次处理函数。

1
2
3
var arr = { 1, 2, 3} //数组
var json = {"name":"lisi","age":20 }
var obj = $(":text");

语法:

$.each( 循环的内容, 处理函数 )

表示使用jquery的each,循环数组,每个数组成员,都会执行后面的“处理函数”一次。

$: 相当于java的一个类名

each:类中的静态方法。
静态方法调用,使用类名.方法名称

处理函数:

function(index, emelent) :

  • index, element都是自定义的形参, 名称自定义。
  • index:循环的索引
  • element:数组中的成员

js循环数组:

1
2
3
4
5
6
7
8
9

for(var i=0;i<arr.length;i++){
var item = arr[i]; //数组成员
//操作数组成员
shuchu( i , item);
}
function shuchu(index, emlemnt){
输出index ,element
}

循环jquery对象

jquery对象就是dom数组
jquery对象.each( function(index,element) {} )

在jquery中给dom对象绑定事件

语法

$(选择器).事件名称( 事件的处理函数)

  • $(选择器):定位dom对象, dom对象可以有多个, 这些dom对象都绑定事件了
  • 事件名称:就是js中事件去掉on的部分, 例如 js中的单击事件 onclick(),jquery中的事件名称,就是click,都是小写的。
  • 事件的处理函数:就是一个function ,当事件发生时,执行这个函数的内容。

例如给id是btn的按钮绑定单击事件:

1
2
3
$("#btn").click(funtion(){
alert("btn按钮单击了")
})

on 事件绑定

$(选择器).on( 事件名称 , 事件的处理函数)

  • 事件名称: 就是js事件中去掉on的部分, 例如js中onclick ,这里就是click

  • 事件的处理函数: function 定义。

    例如,

1
2
<input type="button" id="btn">
$("#btn").on("click", function() { 处理按钮单击 } )

使用jquery的函数,实现ajax请求的处理

没有jquery之前,使用XMLHttpRequest做ajax,有4个步骤。jquery简化了ajax请求的处理。
使用三个函数可以实现ajax请求的处理。

1) $.ajax() : jquery中实现ajax的核心函数。
2) $.post() : 使用post方式做ajax请求。
3) $.get() : 使用get方式发送ajax请求。

$.post()和$.get() 他们在内部都是调用的 $.ajax()

$.ajax函数

介绍 $.ajax函数的使用, 函数的参数表示请求的url, 请求的方式,参数值等信息。
$.ajax()参数是一个json的结构。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$.ajax({名称:值, 名称1:值1..... })
$.ajax({async:true ,
contentType:"application/json" ,
data: {name:"lisi",age:20 },
dataType:"json",
error:function(){请求出现错误时,执行的函数
},
success:function( data ) {
// data 就是responseText, 是jquery处理后的数据。
},
url:"bmiAjax",
type:"get"
}
)

json结构的参数说明:

  1. async:是一个boolean类型的值, 默认是true ,表示异步请求的。可以不写async这个配置项。
    xmlHttp.open(get,url,true),第三个参数一样的意思。

  2. contentType: 一个字符串,表示从浏览器发送服务器的参数的类型。 可以不写。
    例如表示请求的参数是json格式的, 可以写application/json

  3. data: 可以是字符串,数组,json,表示请求的参数和参数值。 常用的是json格式的数据

  4. dataType: 表示期望从服务器端返回的数据格式,可选的有: xml , html ,text ,json
    使用$.ajax()发送请求时, 会把dataType的值发送给服务器,servlet能够读取到dataType的值,就知道浏览器需要的是 json或者xml的数据,那么服务器就可以返回需要的数据格式。

  5. error: 一个function ,表示当请求发生错误时,执行的函数。
    error:function() { 发生错误时执行 }

  6. sucess:一个function , 请求成功了,从服务器端返回了数据,会执行success指定函数
    之前使用XMLHttpRequest对象, 当readyState==4 && status==200的时候。

  7. url:请求的地址

  8. type:请求方式,get或者post, 不用区分大小写。 默认是get方式。

    主要使用的是 url , data ,dataType, success。

jQuery

动态代理初步

动态代理(理解): 基于反射机制。

掌握程度

  1. 什么是动态代理
    使用jdk的反射机制,创建对象的能力, 创建的是代理类的对象。 而不用你创建类文件。不用写java文件。 动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。 jdk动态代理,必须有接口,目标类必须实现接口, 没有接口时,需要使用cglib动态代理。
  1. 动态代理的作用
    可以在不改变原来目标方法功能的前提下, 可以在代理中增强自己的功能代码。
    比如:你所在的项目中,有一个功能是其他人(公司的其它部门,其它小组的人)写好的,你可以使用。
    GoNeng.class , GoNeng gn = new GoNeng(), gn.print(); 当这个功能, 不能完全满足当前项目需要时,用代理实现 gn.print()调用, 增加功能, 而不用更改原来的 GoNeng文件。

使用代理模式的作用

1.功能增强: 在原有的功能上,增加了额外的功能。 新增加的功能,叫做功能增强。
2.控制访问: 代理类控制目标访问,例如商家不让用户访问厂家。

实现代理的方式

静态代理 :

1)代理类是自己手工实现的,自己创建一个java类,表示代理类。
2)同时所要代理的目标类是确定的。
特点: 1)实现简单 2)容易理解。
缺点:
当项目中目标类和代理类很多时候,有以下的缺点:
1)当目标类增加了, 代理类可能也需要成倍的增加。 代理类数量过多。
2) 当接口中功能增加了或修改了,会影响众多的实现类。

动态代理

在程序执行过程中,使用jdk的反射机制,创建代理类对象, 并动态的指定要代理目标类。

换句话说: 动态代理是一种创建java对象的能力,让你不用手动创建代理类,就能创建代理类对象。

动态代理的实现

  1. jdk动态代理(理解): 使用java反射包中的类和接口实现动态代理的功能。

                  反射包 java.lang.reflect , 里面有三个类 : InvocationHandler , Method, Proxy.
    
                2. cglib动态代理(了解): cglib是第三方的工具库, 创建代理对象。
                             cglib的原理是继承, cglib- 通过继承目标类,创建它的子类,在子类中重写父类中同名的方法, 实现功能的修改。
    
    • 因为cglib是继承,重写方法,所以要求目标类不能是final的, 方法也不能是final的。
  • cglib的要求目标类比较宽松, 只要能继承就可以了。cglib在很多的框架比如 mybatis ,spring框架中都有使用。

jdk动态代理:

反射, Method类,表示方法。类中的方法。 通过Method可以执行某个方法。

jdk动态代理的实现

反射包 java.lang.reflect , 里面有三个类 : InvocationHandler , Method, Proxy.

InvocationHandler 接口(调用处理器):

就一个方法invoke():表示代理对象要执行的功能代码。代理类要完成的功能就写在invoke()方法中。

代理类完成的功能:

  1. 调用目标方法,执行目标方法的功能
  2. 功能增强,在目标方法调用时,增加功能。

方法原型:

1
public Object invoke(Object proxy, Method method, Object[] args)

参数:

  • Object proxy: jdk创建的代理对象,无需赋值。
  • Method method:目标类中的方法,jdk提供method对象的
  • Object[] args: 目标类中方法的参数, jdk提供的。

使用步骤

  1. 创建类实现接口InvocationHandler

  2. 重写invoke()方法, 把原来静态代理中代理类要完成的功能,写在这。

Method类:

表示方法的, 确切的说就是目标类中的方法。

作用:

通过Method可以执行某个目标类的方法,method.invoke(目标对象,方法的参数)

1
2
Object ret = method.invoke(service2, "李四");
说明: method.invoke()就是用来执行目标方法的。

Proxy类

核心的对象,创建代理对象。之前创建对象都是 new 类的构造方法()。现在使用Proxy类的方法,代替new的使用。

方法

静态方法 newProxyInstance()

作用

创建代理对象。

参数

1
2
3
4
5
public static Object newProxyInstance(
ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h
)
  • ClassLoader loader 类加载器,负责向内存中加载对象的。 使用反射获取对象的ClassLoader
    如:类a , a.getCalss().getClassLoader(), 目标对象的类加载器
  • Class<?>[] interfaces: 接口, 目标对象实现的接口,也是反射获取的。
  • InvocationHandler h : 自己写的,代理类要完成的功能。
  • 返回值:就是代理对象

实现动态代理的步骤:

  1. 创建接口,定义目标类要完成的功能

  2. 创建目标类实现接口

  3. 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能

    • 调用目标方法

    • 增强功能

  4. 使用Proxy类的静态方法,创建代理对象。 并把返回值转为接口类型。