一、Ajax

Ajax

  • asynchronous(异步) javascript and xml,主要作用是发送异步请求

  • 传统请求 - 同步请求

    • 发送请求方式:地址栏请求,HTML页面超链接请求,HTML页面表单请求,通过location.href发送请求
    • 同步请求存在的缺陷
      • 上一次请求没有响应回来之前,无法继续发送下一次请求,属于阻塞式请求
      • 同步请求响应的是一整张页面,会丢弃之前的页面,浪费资源,用户体验差
Ajax发送异步请求
  • 发送异步请求的核心对象:js中的一个内置对象 xhr
    • 创建xhr对象:
      • IE7版本以前:xhr = new ActiveXObject(“Microsoft.xmlhttp”);
      • IE7浏览器及其以后的版本和非IE浏览器:xhr = new XMLHttpRequest();
<--
处理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>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值