php知识点未掌握的知识@IT·互联网

AJAX技术

2017-06-09  本文已影响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();

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方式就不能改变,只能异步请求。

    <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>

***
####~~~欢迎指正交流...
上一篇下一篇

猜你喜欢

热点阅读