AJAX技术

作者: 明天你好向前奔跑 | 来源:发表于2017-06-09 15:43 被阅读203次

    AJAX

    一、介绍

    AJAX : Asychronous Javascript And XML,指异步JavaScript及XML。是指一种创建交互式网页应用的网页开发技术。

    AJAX 是一种用于创建快速动态网页的技术。

    通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

    传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。

    二、使用AJAX

    1. JS原生AJAX[了解]

    通过查询W3C文档使用JS原生AJAX。

    一般可分为五步:

    1. 创建AJAX对象
    2. 绑定监听事件---监听服务器是否响应数据了
    3. 绑定请求的服务器地址
    4. 发送请求
    5. 服务器响应成功执行的函数
    
    //1.创建对象
    xmlhttp = new XMLHttpRequest();
    //2.绑定监听事件---监听服务器是否响应
    xmlhttp.onreadystatechange = function() {
        //5.服务器响应成功执行的函数
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            alert(xmlhttp.responseText);
        }
    }
    //3.绑定请求路径
    xmlhttp.open("GET", "${pageContext.request.contextPath}/demo", true);
    //4.发送请求
    xmlhttp.send();
    
    • 服务器状态码(readyState、status):

        readyState :
      
        0 :  XMLHttpRequest对象没有完成初始化。即:刚刚创建。
      
        1 :  XMLHttpRequest对象开始发送请求.调用了open方法,但还没有调用send方法,请求还未发出。
      
        2 :  XMLHttpRequest对象的请求发送完成。但服务器还未响应
      
        3 :  XMLHttpRequest对象开始读取响应,还没有结束收到了所有的响应消息头,但正文还没有完全收到
      
        4 :  XMLHttpRequest对象读取响应结束
      
      
        status :
      
        200 :   OK .服务器接收到请求并已响应。
        400 :   无法找到请求的资源。
        403 :   没有访问权限
        404 :   访问的资源不存在
        500 :   服务器内部错误
      

    2. JQurey的AJAX【重点】

    2.1 get方式

    <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
    <script type = "text/javascript">
        $.get(
            url,    //请求的地址路径
            params,     //发送到服务器的参数
            function(){},   //回调函数,服务器响应成功后执行的函数
            type        //一般为json和text,默认text。服务器返回的数据格式
        );
    </script>
    

    例如:

    $.get(
        "${pageContext.request.contextPath}/demo2",//url,请求访问的路径
        {name:"zhangsan",age:20},//要传递到服务器的参数
        function(data) {    //响应成功后执行的函数,data是服务器返回的数据
            alert(data);
        },
        "text"//服务器返回的数据格式
    );  
    

    2.2 post方式

    与get方式一样,只需要把$.get()改为$.post()即可
    
    <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
    <script type = "text/javascript">
        $.post(
            url,    //请求的地址路径
            params,     //发送到服务器的参数
            function(){},   //回调函数,服务器响应成功后执行的函数
            type        //一般为json和text,默认text。服务器返回的数据格式
        );
    </script>
    

    例如:

    $.post(
        "${pageContext.request.contextPath}/demo2",//url,请求访问的路径
        {"name":"yom","age":10},//要传递到服务器的参数
        function(data) {    //响应成功后执行的函数,data是服务器返回的数据
            alert(data);
        },
        "text"//服务器返回的数据格式
    );
    

    2.3 ajax方式

    get与post是ajax方式的简化,用get和post方式可以节省不少代码。
    但ajax的功能更多,他可以指定是否同步或异步,而get和post方式就不能改变,只能异步请求。
    
    • JQuery的包的路径一定要导入并且要正确否则就会失败,js文件放在web-content下新建的js文件夹中,路径前不要加'/'
    • ajax方式和get与post的异步请求格式有个小区别,就是ajax的格式是json格式,前后都有大括号,中间为key:value的键值对形式。两个键值对之间以逗号隔开。
    
        <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
    
        <input type="button" value="ajax(ajax方式异步请求)" onclick="fn()" />
    
        <script type="text/javascript">
            function fn() {
                $.ajax({
                    type : "POST",//请求方式
                    async : true,//是否异步,true为异步,false为同步
                    url : "${pageContext.request.contextPath}/demo3",//请求的服务器路径
                    data : "name=小明",//请求传递的参数
                    success : function(data) {//响应成功后执行的函数,这里的data是指服务器传递回来的数据
                        alert(data.name);
                        alert(data.age);
                    },
                    dataType : "json" //服务器响应的数据格式
                });
            }
        </script>   
    

    三、案例

    1. 案例一:异步校验用户名是否已经存在

    思路:

    1. 准备用户数据库,与注册页面。
    2. 搭建开发环境,数据库相关的jar包:驱动,c3p0,配置文件,dbutils。
    3. 新建工程,创建包结构:web-service-dao
    4. 具体实现。servlet---service---dao数据库查询并返回结果.
        1. 在jsp页面获取到用户输入的用户名
        2. 用异步请求的技术AJAX将用户输入的用户名提交到服务器。
        3. dao层查询,返回一个User对象。
        4. 新建ResultBean的bean类,servlet判断User对象是否为空设置ResultBean的值。
            这个对象存储了返回的消息。将其封装成json响应回客户端。
    5. 客户端解析json数据。
    

    代码实现:

    1. 准备数据库与注册页面

    2. 准备开发需要的jar包与配置文件,工具类JDBCUtils

    public class JDBCUtils {
        private static DataSource ds = new ComboPooledDataSource();// c3p0默认配置获取连接池
        // 可以认为是与线程绑定的获取连接的Map集合
        private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
    
        // 获取连接池的方法
        public static DataSource getDataSource() {
            return ds;
        }
    
        // 通过连接池获取连接的方法
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
        }
    
        // 从ThreadLocal中获取与线程绑定的连接Connection
        public static Connection getConnectionTL() throws SQLException {
            Connection connection = threadLocal.get();
            if (connection == null) {
                threadLocal.set(getConnection());
                connection = threadLocal.get();
            }
            return connection;
    
        }
    
        // 开启事务的方法
        public static void startTransaction() throws SQLException {
            Connection connection = getConnectionTL();
            connection.setAutoCommit(false);
        }
    
        // 提交事务并释放资源的方法
        public static void commitAndRelease() throws SQLException {
            Connection connection = getConnectionTL();
            connection.rollback();
            if (connection != null) {
                connection.close();
                // 这里为什么connection关闭后还要设置为null呢?
                // 因为在关闭close的时候可能出现了异常导致关闭失败,这个时候connection就处于一种未知的状态,这种情况下垃圾回收器gc就不能将他回收
                // 因此在后面将它设为null,这样即使出现异常也能被垃圾回收器关闭
                connection = null;
            }
            threadLocal.remove();
        }
    
        // 回滚事务并释放资源的方法
        public static void rollbackAndRelease() throws SQLException {
            Connection connection = getConnectionTL();
            if (connection != null) {
                connection.close();
                connection = null;
            }
            threadLocal.remove();
        }
    }
    

    3. 新建工程,创建包结构:web-service-dao

    4. 后台功能的具体实现

    1. 在jsp页面获取用户输入框,绑定失去焦点事件,用异步请求将获取到的用户名发送到服务器端。
    
    使用jquery的ajax前一定要导入jquery。
    
    <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
    <script type="text/javascript">
        $(function(){   //页面加载完成时间
            //获取输入用户名的输入框对象并为其绑定onblur事件
            $("#username").blur(function() {
                //获取到用户输入的用户名
                var $username = $("#username").val();
                //使用AJAX技术将获取到的用户名传到服务器后台进行查询
                $.post(
                    "${pageContext.request.contextPath}/checkUsername",//url,发送请求到服务器的地址
                    "username="+$username,//请求的参数
                    function(data) {//服务器响应成功后执行的函数
                        //data为服务器响应回的json数据,将其解析在用户名输入框的下方,获取到该div标签对象
                        $("#checkUsername").html(data.message);                                 
                        if(data.isExist) {
                            $("#checkUsername").css("color","red");
                        }else {
                            $("#checkUsername").css("color","green");
                        }
                    },
                    "json"//服务器响应的数据格式
                );
            });
        });
    </script>   
    
    
    
    2. 服务器端servlet接收异步请求发送过来的参数(用户输入的用户名),将它传到service层处理,返回查询到的用户User。
    在servlet层对User进行判断,根据User的是否为null设置bean类ResultBean中的isExsit与message值。将bean类写回客户端。
    
    // 编码
    request.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");
    // 获取异步请求AJAX传递的参数username
    String username = request.getParameter("username");
    
    // 调用业务层
    try {
        CheckNameService service = new CheckNameService();
        User user = service.checkUsername(username);
    
        // 在这里使用一个存储用户是否存在boolean和传回客户端信息的bean内来封装数据
        ResultBean resultBean = new ResultBean();
        // 判断用户名为username的用户是否存在,给resultBean赋值
        if (user == null) {
            resultBean.setExist(false);// 说明用户名不存在
            resultBean.setMessage("用户名不存在,可以使用");
        } else {
            resultBean.setExist(true);// 说明用户存在
            resultBean.setMessage("用户名已存在!");
        }
    
        // 将封装后的resultBean转化成json格式的字符串,这里要使用到Gson工具包
        Gson gson = new Gson();
        String json = gson.toJson(resultBean);
        System.out.println(json);
        // 将封装好的json字符串写回客户端解析
        response.getWriter().write(json);
    
    } catch (SQLException e) {
        e.printStackTrace();
    }
    
    
    3. 创建servlet层用到的两个bean类:User与ResultBean
    
    4. service层调用dao层。
        CheckNameDAO dao = new CheckNameDAO();
        return dao.checkUsername(username); 
    
    5. dao层连接数据库查询是否存在该用户名的用户。
    
        QueryRunner runner = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select * from user where name=?";
        return runner.query(sql, new BeanHandler<User>(User.class),username);
    
    6. dao层返回值为User,servlet层判断是否存在设置ResultBean的值,客户端接收resultBean的json值进行解析,添加到对应要显示的位置即可。
    这在前面的代码中也已经显示了。
    

    5. 效果图

    img01.png img02.png

    2. 案例二: 站内异步搜索

    需求:模仿淘宝搜索宝贝,每次输入一个关键字时,异步请求服务器,去数据库进行模糊查询,将查询到的商品名返回到客户端显示。

    分析:

    1. 在要添加该功能的div标签后添加一个div标签,完成布局。
    2. 获取到搜索框的对象,对其进行mouseup监听,每次触发都发起异步请求,异步请求将搜索框内的数据传送到服务器查询。
    3. 服务器servlet接收到异步请求ajax发送过来的参数,将其传递到service--dao进行模糊查询,返回查询到的商品集合,
        将其封装成json字符串响应回客户端。
    4. 客户端接收到响应的数据,解析json并将其添加到添加的div标签内。
    

    2.1 jsp布局

    在用户的search搜索输入框的div中添加一个div,为搜索联想框.
    css属性:
        1. display为none,不可见,当输入关键字keyup监听时将其设置为block可见。
        2. position:absolute。设置该div是独立的,防止对父标签div的布局影响。
        3. z-index:999.设置z轴上的优先级,数字越大布局越在上方。
        
    <div id="returnKey" style="display:none;width: 196px;height: 80px;position: 
        absolute;background-color: white;z-index: 999" ></div>
    
    
    获取到搜索输入框元素,为搜索输入框添加键盘监听事件:
    通过监听事件,用户每次输入关键字,松开键时触发searchKeyWords()方法。
    该方法获取到用户输入的关键字数据,利用异步请求ajax技术将其发送到服务器查询数据库。
    function中的data为服务器返回的商品List集合,遍历集合,在添加的搜索联想框div中添加div标签,将商品的名字一一添加进去。
    
    //用户输入搜索关键字产生的联想
    function searchKeyWords() {
        $("#returnKey").css("display","block");
        //获取搜索框的输入的关键字
        var $keyWords = $("#searchWords").val();
        //使用异步请求将获取到的关键字发送到服务器进行查询
        if($keyWords!="") {
            $.post(
                "${pageContext.request.contextPath}/searchWords",//url
                "keyWords="+$keyWords,//请求发送的参数
                function(data) {//服务器响应成功后执行的函数
                    //将服务器响应回的数据解析写到id为returnKey的div中
                    var resultString = "";
                    for (var i = 0; i < data.length; i++) {
                        resultString += "<div onclick='insertContent(this)' onmouseover='changeColor(this)' onmouseout='backColor(this)' style='margin-left: 5px;margin-top: 3px'>"+data[i].pname+"</div>";
                    }
                    $("#returnKey").html(resultString);
                },
                "json"//服务器返回的数据格式
                );
            }
        }
    </script>   
    

    2.2 服务器Servlet处理异步请求发送过来的关键字

    servlet将请求的参数keyWords传至service层/dao层在数据库中模糊查询,将查询到的商品数据,转换为json字符串写回客户端。
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //编码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //获取ajax传递过来的参数keywords
        String keyWords = request.getParameter("keyWords");
        try {
            //调用业务逻辑层,将获取到的keywords传递到service---dao
            SearchKeyWordsService service = new SearchKeyWordsService();
            List<Product> list =  service.searchKeyWords(keyWords);
            //将返回的list商品数据转化为json格式的字符串传回客户端
            Gson gson = new Gson();
            String json = gson.toJson(list);
            
            //写回客户端
            response.getWriter().write(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    

    2.3 service层

    SearchKeyWordsDAO dao = new SearchKeyWordsDAO();
    return dao.searchKeyWords(keyWords);
    

    2.4 dao层

    sql语句limit限制查询的条数,这样就能控制显示的联想数量
    
    QueryRunner runner = new QueryRunner(JDBCUtils.getDataSource());
    String sql = "select * from products where pname like ? limit 3"; 
    return runner.query(sql, new BeanListHandler<Product>(Product.class), "%"+keyWords.trim()+"%");
    

    2.5 jsp界面优化

    1. 用户选择关键字后,将该关键字添加到输入框中
      1. 关键字添加到输入框后,联想框的display属性再次设置为none
    2. 用户将鼠标移至联想条目时,变色,移出时,恢复
    
        <script type="text/javascript">
        //鼠标移到条目上方时给搜索条目增加背景色
        function changeColor(obj) {
            $(obj).css("background-color","#ccc");
        }
        //鼠标移出条目上方时给搜索条目还原背景色
        function backColor(obj) {
            $(obj).css("background","white");
        }
        
        //用户点击联想商品名称时,将该商品名添加到搜索框中
        function insertContent(obj) {
            var $pname = $(obj).html();//获得搜索联想的商品名
            //点击时将该商品名加入到搜索输入框中
            $("#searchWords").val($pname);
            //隐藏联想框
            $("#returnKey").css("display","none");
        }
        </script>
    
    ***
    ####~~~欢迎指正交流...

    相关文章

      网友评论

      本文标题:AJAX技术

      本文链接:https://www.haomeiwen.com/subject/itlfqxtx.html