JavaWeb开发知识总结(Ajax,JSON)

JavaWeb开发知识总结(Ajax,JSON)

1. Ajax技术

AJAX技术:Asynchronous JavaScript and XML(异步的JavaScript和XML)。

AJAX不是新的编程语言,而是一种使用现有标准的新方法。

AJAX技术可以在不刷新整个网页的情况和数据库进行交互获取数据,进而可以实现网页的局部刷新地址栏的地址不发生变化。

1.1 同步与异步的区别:

同步

这里写图片描述

AJAX使用的异步请求的模式,需要注意:Ajax向服务器发送请求后,服务器向Ajax返回数据;服务器端以转发或重定向或者直接向客户端写回数据,这些数据或转发或重定向的网页都会作为Ajax的返回值,而不会直接跳转到服务器转发或重定向到的页面。

1.2 XMLHttpRequest对象–Ajax技术的基础

​ Ajax技术是以javascript中的XMLHttpRequest对象为基础进行实现的。XMLHttpRequest对象可以在后台与服务器交换数据。

1.2.1 XMLHttpRequest对象常用API
常用API类型说明
readyState属性返回Ajax请求的当前状态
onreadystatechange属性指定当readyState属性改变时的事件处理函数
status属性获取当前请求的http响应的状态码,200,404等
responseText属性获取服务器响应数据的字符串形式
responseXML属性将响应信息格式化为Xml Document对象并返回
open(请求方式,请求地址,是否异步,用户名,密码)方法创建一个新的http请求,并指定此请求的方式、请求的URL以及验证信息
send(数据)方法发送请求到http服务器并接收响应,参数是想服务发送的数据,当无参数时,需传递null
setRequestHeader(头信息, 信息值)方法单独指定请求的某个http头,一般用于处理post方式提交数据的处理

readyState属性的状态码及其含义:

readyState状态码含义
0 (未初始化)对象已建立,但是尚未初始化(尚未调用open方法)
1 (初始化)对象已建立,尚未调用send方法
2 (发送数据)send方法已调用,但是当前的状态及http头未知
3 (数据传送中)已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误
4 (完成)数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据
1.2.2 XMLHttpRequest对象创建

由于浏览器间对Ajax技术的支持不兼容,则不同的浏览器创建XMLHttpRequest对象的方式有所不同,chrome和Firefox等浏览器中内置XMLHttpRequest对象,可以直接使用,而IE的浏览中需要通过ActiveXObject对象创建XMLHttpRequest对象,写出通用的创建XMLHttpRequest对象的方法如下(重要):

// 创建XMLHttpRequest对象的方法
function createXmlHttp(){
   var xmlHttp;
   try{ // Firefox, Opera 8.0+, Safari, IE7+, Safari
        xmlHttp=new XMLHttpRequest();
    }
    catch (e){
       try{// IE6,IE5 IE浏览器
             xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
          }
        catch (e){
          try{
             xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
          }
          catch (e){}
          }
    }
    return xmlHttp;
 }
1.2.3 Ajax的使用步骤
  1. 创建XMLHttpRequest对象;
  2. 设置XMLHttpRequest对象状态改变触发的函数,响应的回调函数;
  3. 设置向服务器发送请求的参数;
  4. 向服务器发送请求。

使用GET方式向服务器请求数据:

// 此方法是用于向服务器发送get请求,方法可以通过元素的事件触发
function ajax_get() {
    // 1.创建XMLHttpRequest对象
    var xhr = createXmlHttp(); // 创建XMLHttpRequest对象通用方法
    // 2.设置XMLHttpRequest对象状态改变触发的函数,回调函数
    xhr.onreadystatechange=function(){ // 当服务器响应时会调用此函数
        if(xhr.readystate == 4){ // 4代表请求发送成功
            if(xhr.status == 200){ // 200代表响应的状态码
                // 获得服务器响应数据文本形式
                var data = xhr.responseText;
                // 输出数据
                alert(data);
            }
        }
    }
    // 3.设置发送请求的参数,并通过url传递参数
    xhr.open("GET","/JavaWeb_site/DemoServlet?username=somnus&password=somnus",true);
    // 4.发送请求
    xhr.send(null); // send的参数一般用于POST方式的传递参数,但无参数时,需传入null
}

使用POST方式向服务器请求数据:

function ajax_post() {
    // 1.创建XMLHttpRequest对象
    var xhr = createXmlHttp(); // 创建XMLHttpRequest对象通用方法
    // 2.设置XMLHttpRequest对象状态改变触发的函数,回调函数
    xhr.onreadystatechange=function(){ // 当服务器响应时会调用此函数
        if(xhr.readystate == 4){ // 4代表请求发送成功
            if(xhr.status == 200){ // 200代表响应的状态码
                // 获得服务器响应数据文本形式
                var data = xhr.responseText;
                // 输出数据
                alert(data);
            }
        }
    }
    // 3.设置发送请求的参数,并通过url传递参数
    xhr.open("POST","/JavaWeb_site/DemoServlet",true);
    // post方式需要设置请求头才能传递参数,此方法必须在open方法调用后才能调用
    // 设置请求头实际上将数据封装成表单形式的键值对数据,form表单本身默认会将表单数据封装成键值对形式
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    // 4.发送请求
    xhr.send("username=somnus&password=somnus"); // send的参数一般用于POST方式的传递参数,但无参数时,需传入null
} 

2. jQuery实现Ajax技术

​ jQuery实现的Ajax是对传统的Ajax的封装,jQuery对原始的Ajax的实现步骤进行了封装,将XMLHttpRequest对象的创建、设置状态监听器、设置请求路径及发送请求进行了封装,并提供函数的方法使用Ajax,jQuery提供了6中使用Ajax的函数,下面总结4个较为常用的函数及1个序列化form表单数据的方法:

函数类型说明
JQ对象.load(请求路径, [参数], [响应成功的回调函数])Ajax请求载入远程HTML文件代码并插入至JQ对象中,默认使用的post请求的方式
$.get(请求路径, [参数], [响应成功的回调函数], [返回数据格式])Ajax请求通过get方式发送请求,只能在响应成功的情况才会调用回调函数
$.post(请求路径, [参数], [响应成功的回调函数], [返回数据格式])Ajax请求通过post方式发送请求,只能在响应成功的情况才会调用回调函数
$.ajax([请求路径, ][ Ajax请求的设置])Ajax请求类似Ajax传统的实现方式,所有的参数需要自己设定,功能更灵活,可以在回调函数中定义不同响应状态下的处理函数
serialize()Ajax数据处理方法序列表单数据内容为字符串,一般用于将发送POST请求的表单数据序列化为键值对的字符串后作为POST请求的参数

案例代码:

<!--index.jsp-->
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${pageContext.request.contextPath }/ajax/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    $(function(){
        $("#btn").click(function(){
            // get方式的Ajax请求
            $.get("${ pageContext.request.contextPath}/ServletDemo2",{"username":"somnus","password":"somnus"},function(data){
                $("#div").html(data);
            });
        });
    });

    $(function() {
        // load方式的Ajax请求
        $("#btn2").click(function() {
            $("#div2").load("${ pageContext.request.contextPath}/ServletDemo2",{"username":"somnus","password":"somnus"});
        });
    });

    $(function() {
        $("#btn3").click(function(){
            // post方式的Ajax请求
            $.post("${ pageContext.request.contextPath}/ServletDemo2",{"username":"somnus","password":"somnus"},function(data){
                $("#div3").html(data);
            });
        });
    });
    $(function() {
        $("#btn4").click(function(){
            // ajax方式的Ajax请求
            $.ajax({type:"GET",url:"${ pageContext.request.contextPath}/ServletDemo2?username=somnus&password=somnus",context: document.body,success:function(data){
                $("#div4").html(data);
            }});
        });
    });
</script>
</head>
<body>
<h1>JQuery中Ajax的操作</h1>
<div id="div" style="width: 200px;height:200px">
</div>
<input type="button" value="test1" id="btn"/>
<div id="div2" style="width: 200px;height:200px">
</div>
<input type="button" value="test2" id="btn2"/>
<div id="div3" style="width: 200px;height:200px">
</div>
<input type="button" value="test3" id="btn3"/>
<div id="div4" style="width: 200px;height:200px">
</div>
<input type="button" value="test4" id="btn4"/>
</body>
</html>
// ServletDemo2.java
public class ServletDemo2 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 接收get方式请求,并将数据返回
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        response.getWriter().println(username+"--"+password);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 接收post方式请求,并将数据返回
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        response.getWriter().println(username+"--"+password);
    }
}

3. Ajax中响应数据的类型

​ Ajax发送请求后接受到的响应的数据的格式可以是:文本数据HMTL格式数据XML格式数据JSON格式数据;当在Servlet中向Ajax响应数据时,如果不设置数据的响应格式,默认的是文本数据;Servlet向Ajax响应XML数据时需设置response.setContentType("text/xml;charset=UTF-8");,返回HTML格式数据时需要设置response.setContentType("text/html;charset=UTF-8");,返回JSON数据时可以不设置数据格式,但为防止json数据中的中文出现乱码,可以设置和HTML一样的数据格式。

3.1 Ajax接收文本类型的响应数据

案例:用户注册时根据用户输入的用户名实时校验输入的用户名是否可用

<!--register.jsp-->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>用户注册</title>
<!-- 引入css文件 -->
<link rel="stylesheet"href="${pageContext.request.contextPath }/regist_search/css/bootstrap-theme.min.css" />
<link rel="stylesheet"href="${pageContext.request.contextPath }/regist_search/css/bootstrap.min.css" />
<!-- 引入js文件 -->
<script type="text/javascript"src="${pageContext.request.contextPath }/regist_search/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript"src="${pageContext.request.contextPath }/regist_search/js/bootstrap.min.js"></script>
<script type="text/javascript">
    $(function() {
        // 用户名输入框的失去焦点及按键弹起事件
        $("#username").bind("keyup blur",function() {
            if ($(this).val() != "") {
                $.post("${pageContext.request.contextPath}/UserRegisterServlet",
                {"username" : $(this).val()},
                function(data) {
                    if (data == 1) {
                        $("#tip").html("<font color='green'>用户名可用</font>");
                        $("#regbtn").prop("disabled",false);
                    }
                    if (data == 0) {
                        $("#tip").html("<font color='red'>该用户名已被占用</font>");
                        $("#regbtn").prop("disabled",true);
                    }
                });
            } else {
                // 当用户名输入框为空时,清空提示信息,并将注册按钮禁用
                $("#tip").html("");
                $("#regbtn").prop("disabled", true);
            }
        });
    });
</script>
</head>
<body>
    <div class="container">
        <!-- 注册 -->
        <div
            class="row"
            style="background: url(img/regist_bg.jpg);height: 500px;">
            <div
                class="col-md-offset-2 col-md-8"
                style="border: 5px solid #245580;margin-top: 30px;background-color: whitesmoke;">
                <div
                    class="row"
                    style="padding-top: 15px;padding-left: 30px;">
                    <div class="row">
                        <div
                            class="col-md-offset-1 col-sm-offset-1 col-sm-5 col-md-5 col-xs-10"
                            style="padding-left: 0px;">
                            <h4>
                                <font color="#337AB7"><strong>用户注册</strong></font><small>
                                    USER REGISTER</small>
                            </h4>
                        </div>
                    </div>
                    <form class="form-horizontal">
                        <div class="form-group">
                            <label
                                for="username"
                                class="col-sm-2 control-label">用户名</label>
                            <div class="col-md-5 col-sm-10">
                                <input
                                    type="text"
                                    class="form-control"
                                    name="username"
                                    id="username"
                                    placeholder="请输入用户名"> <span id="tip"></span>
                            </div>
                        </div>

                        <div class="form-group">
                            <label
                                for="province"
                                class="col-sm-2 control-label">籍贯</label>
                            <div
                                class="col-sm-10 form-control-static"
                                style="padding-left: 0px;">
                                省份:<select
                                    name="province"
                                    id="province">
                                    <option
                                        value=""
                                        selected="selected">--请选择--</option>
                                </select> &nbsp;&nbsp;城市:<select
                                    name="city"
                                    id="city">
                                    <option
                                        value=""
                                        selected="selected">--请选择--</option>
                                </select>
                            </div>
                        </div>
                        ...
                        <div class="form-group">
                            <div class="col-sm-offset-2 col-sm-10">
                                <button
                                    type="submit"
                                    id="regbtn"
                                    class="btn btn-success">注册</button>
                                &nbsp;&nbsp;&nbsp;&nbsp;
                                <button
                                    type="reset"
                                    class="btn btn-primary">重置</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</body>
</html>
/**
 * 用户注册的Servlet    UserRegisterServlet.java
 */
public class UserRegisterServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置request缓冲区的编码格式,防止post方式接收中文乱码
        request.setCharacterEncoding("UTF-8");
        String username = request.getParameter("username");
        try{
            // 调用业务层方法查询指定用户名的用户是否存在
            UserService userService = new UserService();
            User checkUser = userService.checkUsername(username);
            // 当查询指定用户名的用户为null,表示该用户不存在
            if(checkUser == null) {
                // 返回1代表没有查询到,用户名可用
                response.getWriter().println(1);
            } else {
                // 返回0,代表数据库中存在该用户名
                response.getWriter().println(0);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

3.2 Ajax接收HTML类型的响应数据

Servlet向Ajax返回HTML格式的数据,本质就是返回的带有html标签的数据。

案例:注册页面的省市联动中在页面加载时通过POST请求获取省份的信息,并将获得省份的信息添加到省份的下拉框中;实现的思想是:页面加载时通过post请求省份信息,Servlet将查询到身份的信息集合存储到request域中,通过转发到中间页面将集合中的省份信息进行遍历输出为<option> 标签的值,由于中间页面是Servlet向Ajax请求而响应的数据,则中间页面是作为Ajax请求的返回值,在回调函数中将接收的数据直接追加到省份的下拉选项框中即可。

<!--register.jsp    和接收文本数据案例的文件内容相同,就是使用javascript添加省份信息的代码不相同-->
...
<script type="text/javascript">
    $(function() {
        // 页面加载时请求省份的信息
        $.post("${pageContext.request.contextPath}/ProvinceServlet",function(data){
            $("#province").append(data); // 通过中间页面加载省份信息
        });
    });
</script>
...
/**
 * 加载省份信息的Servlet   ProvinceServlet.java
 */
public class ProvinceServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // jsp页面初始化时发送POST方式请求,返回省份的信息
        // 调用业务层获取省份的
        ProvinceService provinceService = new ProvinceService();
        try {
            List<Province> list = provinceService.findProvince();
            // 通过转发到中间页面的方式进行数据的更新
            request.setAttribute("list", list);
            request.getRequestDispatcher("/province.jsp").forward(request, response);   
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
<!--province.jsp-->
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:forEach var="p" items="${ list }">
    <option value="${ p.pname }">${ p.pname }</option>
</c:forEach>

3.3 Ajax接收XML类型的响应数据

​ Servlet向Ajax返回XML格式的数据,需要设置浏览器读取数据的方式response.setContentType("text/xml;charset=UTF-8");,同时还需要将从数据库中查询的数据转换为XML格式,通过工具类第三方的XStreamjar将数据转换为XML格式。

XStream工具类需要两个jar包:xpp3_min-1.1.4c.jarxstream-1.4.4.jar

案例:注册页面的省市联动中在页面加载时通过POST请求获取省份的信息,并将获得省份的信息添加到省份的下拉框中;实现思想是:Servlet中将查询的省份的信息转换为XML格式的数据,在Ajax回调函数中进行XML数据的解析,并将数据追加到省份下拉框中;当省份信息发生变化时,通过get方式获取当前省份对应城市的信息。

<!--register.jsp    和接收文本数据案例的文件内容相同,就是使用javascript添加省份信息的代码不相同-->
...
<script type="text/javascript">
    $(function() {
        // 页面加载时请求省份的信息
        $.post("${pageContext.request.contextPath}/ProvinceServlet",function(data){
            // var p = $(data).children("province");  此方式不能正确的加载数据,暂未弄明白
            // 通过xml数据加载省份信息
            // data代表的返回的数据,查找data中子元素为province的子元素,并遍历
            $(data).find("province").each(function(i,n){  // 使用children方式没有结果
                // 查找province的子元素名为pid并获取标签中文本数据
                var pid = $(this).children("pid").text();
                // 查找province的子元素名为pname并获取标签中文本数据
                var pname = $(this).children("pname").text();
                // 将查询到的数据追加到province的下拉框中
                $("#province").append("<option value='"+pid+"'>"+pname+"</option>");
            });
        },"xml"); // 设置接收数据的格式为xml

        // 当省份下拉框值变化时,改变城市的信息
        $("#province").change(function() {
            // 通过get方式请求当前省份id对应的城市信息
            $.get("${pageContext.request.contextPath}/ProvinceServlet?pid="+$(this).val(),function(data){
            //$("#city").html("<option selected='selected'>--请选择--</option>"); 此方式也可实现
            $("#city")[0].options.length=1;
            $(data).find("city").each(function(){
                var cid = $(this).children("cid").text();
                var cname = $(this).children("cname").text();
                $("#city").append("<option value="+cid+">"+cname+"</option>");
            });
            },"xml");
        });
    });
</script>
...
<!---返回的数据格式是:-->
<list>
  <province>
    <pid>1</pid>
    <pname>河北省</pname>
  </province>
  ...
</list>
/**
 * 加载省份信息的Servlet    ProvinceServlet.java
 */
public class ProvinceServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 根据省份信息的变化获取城市信息
        try {
            // 获取参数中省份的id
            String pid = request.getParameter("pid");
            // 通过省份id获取对应城市的信息
            ProvinceService provinceService = new ProvinceService();
            // 查询城市的信息,封装到list集合中
            List<City> city =provinceService.findCity(pid);
            // 创建XStream对象
            XStream xStream = new XStream();
            // 设置标签
            xStream.alias("city", City.class);
            // 将list数据转换为xml格式
            String cityStr = xStream.toXML(city);
            // 设置数据输出格式
            response.setContentType("text/xml;charset=UTF-8");
            // 输出数据到客户端
            response.getWriter().println(cityStr);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // jsp页面初始化时发送POST方式请求,返回省份的信息
        // 调用业务层获取省份的信息
        ProvinceService provinceService = new ProvinceService();
        try {
            // 将省份的信息封装到List集合中
            List<Province> list = provinceService.findProvince();
            // 将结果数据封装层xml格式
            XStream xStream = new XStream();
            // 修改生成的xml中的标签名,默认是类的全路径
            xStream.alias("province", Province.class);
            // 将list集合数据转换为xml格式
            String xmlStr = xStream.toXML(list);

            // 修改标签名:
            xStream.alias("city", City.class);
            // 将类中属性作为 标签的属性
            // xStream.useAttributeFor(Province.class, "pid");
            // xStream.useAttributeFor(Province.class,"pname");

            // 设置数据输出的格式
            response.setContentType("text/xml;charset=UTF8");
            // 将查询到的数据输出到客户端
            response.getWriter().println(xmlStr);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

3.4 Ajax接收JSON类型的响应数据

JSON数据:

JSON:JavaScript Object Notation,是一种轻量级的数据交换格式,是ECMAScript的子集,javascript可以直接解析json数据。json数据以键值对方式存在。

JSON常见的3种数据格式:
json数据格式格式说明
{"key1":value1,"key2":value2...}键值对数据,相当于是Map集合数据,其中数据相当于是key,可以通过.value获取其中的数据
[{"key1":value01,"key2":value11...},{"key1":value02,"key2":value12...}...]键值对对象的数组形式,相当于是List(数组)集合中存储的Map集合数据
{"name":{"key1":value1,"key2":value2...}}带有名称标示的键值对象数据或者数组
JSON数据的使用:

JSON数据,在Servlet中通过json的工具类将数据转换为json格式的数据,常用的工具类是JSONLib。该工具类常用的类:

JSONLib中常用类作用说明
JSONArray将数组或list集合数据转换为JSON格式数据
JSONObject将Java对象或Map集合数据转换为JSON格式数据

注意事项:在程序中将数据转换为json格式后数据类型时JSON类型,在向客户端输出前需设置response.setContentType("text/xml;charset=UTF-8")防止中文数据乱码,同时在调用response的输出方法时需将json格式的数据转换为String形式。

JSONLib使用需要使用的jar包:

commons-beanutils-1.8.3.jar
commons-collections-3.2.1.jar
commons-lang-2.5.jar
commons-logging-1.1.1.jar
ezmorph-1.0.6.jar
json-lib-2.4-jdk15.jar

案例:注册页面的省市联动中在页面加载时通过POST请求获取省份的信息,并将获得省份的信息添加到省份的下拉框中;实现思想是:Servlet中将查询的省份的信息转换为JSON格式的数据,在Ajax回调函数中循环JSON数据,并将数据追加到省份下拉框中;当省份信息发生变化时,通过get方式获取当前省份对应城市的信息。

<!--register.jsp    和接收文本数据案例的文件内容相同,就是使用javascript添加省份信息的代码不相同-->
<script type="text/javascript">
//使用json作为传输数据的格式
$(function(){
    // 页面加载时初始化省份信息
    // 使用POST方式请求数据
    $.post("${pageContext.request.contextPath}/ProvinceJsonServlet",function(data){
        // 遍历返回的数据集合,将数据追加到身份下拉列表中
        $(data).each(function(i,n){
            // json数据直接使用当前的对象直接.即可
            $("#province").append("<option value='"+n.pid+"'>"+n.pname+"</option>");
        });
    },"json");// 接收的数据格式json

    // 省份信息变化时变动城市信息
    $("#province").bind("change",function(){
        // 通过省份下拉列表的变化,向服务器请求对应省份城市的信息
        $.get("${pageContext.request.contextPath}/ProvinceJsonServlet",{"pid":$(this).val()},function(data){
            // 当省份变化时,初始化城市的信息
            $("#city").html("<option>-请选择-</option>");
            // 遍历城市的信息,将数据追加到城市的下拉列表中
            $(data).each(function(i,n){
                $("#city").append("<option value='"+n.cid+"'>"+n.cname+"</option>");
            });
        },"json"); // 接收的数据格式json
    });
});
</script>
<!--返回的数据格式如下-->
[{"pid":1,"pname":"河北省"},...]
/**
 * 使用json传输数据的Servlet   ProvinceJsonServlet.java
 */
public class ProvinceJsonServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 根据省份ID查询对应的城市信息
        String pid = request.getParameter("pid");
        ProvinceService provinceService = new ProvinceService();
        try {
            // 查询城市的信息集合
            List<City> city = provinceService.findCity(pid);
            // 将list集合的数据转换为json格式
            JSONArray jsonArray = JSONArray.fromObject(city);
            // 设置浏览器打开数据的方式,防止中文数据的乱码
            response.setContentType("text/html;chaeset=UTF-8");
            // 设置response的缓冲区的编码的格式
            response.setCharacterEncoding("UTF-8");
            response.getWriter().println(jsonArray.toString());

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        ProvinceService provinceService = new ProvinceService();
        try {
            // 从数据库中获取省份的信息
            List<Province> province = provinceService.findProvince();

            // 将LIst集合转成JSON:去除其中某些字段
            // JsonConfig config = new JsonConfig(); 创建json转换的配置对象
            // config.setExcludes(new String[]{"pid"}); 将不需要出现在json中的字段放在数组中
            //  使用json将List集合数据转换为json格式并去除指定的配置对象中的字段
            // JSONArray jsonArray = JSONArray.fromObject(list,config); 

            // 将查询到的信息转换为json格式
            JSONArray jsonArr = JSONArray.fromObject(province);

            // 设置输出数据的类型,防止中文乱码
            response.setContentType("text/html;charset=UTF-8");
            // 输出json数据时必须将JSONArray类型转为String类型
            response.getWriter().println(jsonArr.toString());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

3.5 综合案例:模拟百度搜索输入框的提示信息

在搜索框中输入字符时,根据数据的查询的结果给出下拉框给出匹配的关键。实现的思想:给输入框绑定keyup 事件,在事件处理函数中通过Ajax的POST方式向服务器发送请求,在数据库查询与输入的数据相关的关键字,并以json数据形式返回,在Ajax请求的回调函数中将数据显示在输入框下面隐藏的div中,并将div置为可见。

<!--search.jsp-->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>百度搜索</title>
<!-- 引入css文件 -->
<link rel="stylesheet" href="${ pageContext.request.contextPath }/regist_search/css/bootstrap-theme.min.css" />
<link rel="stylesheet" href="${ pageContext.request.contextPath }/regist_search/css/bootstrap.css" />
<!-- 引入js文件 -->
<script type="text/javascript" src="${ pageContext.request.contextPath }/regist_search/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="${ pageContext.request.contextPath }/regist_search/js/bootstrap.min.js"></script>
<script type="text/javascript">
    // 异步加载数据
    $(function() {
        // 当所有的输入框中按键弹起时触发函数
        $("#word").keyup(function() {
            // 获取该输入框的值
            var word = $(this).val();
            // 当输入框不为空时向服务器发送请求
            if (word != "") {
                // 通过Ajax的POST请求方式向服务发送请求
                $.post("${pageContext.request.contextPath}/SearchServlet", 
                    {"word" : word}, // 当前输入框的值,就是后台要检索以此字符开始的关键字
                    function(data) {
                        // 获取数据并将数据加载到div中
                        $("#data").slideDown("slow");
                        // 每次追加数据前将表格中的数据清空
                        $("#tips").html("");
                        // 将保存在json中的数据进行遍历输出
                        $(data).each(function(i, n) {
                            $("#tips").append("<tr><td>" + n.word + "</td></tr>");
                        });

                        // $("#data").html(data);
                        // 将数据鼠标悬浮换色
                        $("#tips td").hover(function() {
                            //  鼠标悬停在当前tr行上时将背景颜色改变
                            $(this).css("background", "#EEE");
                        }, function() {
                            // 鼠标移除时当前tr行的背景色恢复白色
                            $(this).css("background", "white");
                        });
                        // 下列框选择中选项点击时,将表格中值设为输入框的值
                        $("#tips td").click(function() {
                            // 获取当前点击的td的值
                            var val = $(this).text();
                            // 将点击的tr中的文本数据设为输入框的值
                            $("#word").val(val);
                            // 点击后将下拉框隐藏
                            $("#data").hide();
                        });
                }, "json"); // 设置接收的数据格式json
            } else {
                // 当输入框为空时,清除提示信息
                $("#data").hide();
            }
        });
    });
</script>
</head>
<body>
    <div class="container-fluid">
        <div class="row text-center" style="margin-top: 160px;">
            <div class="col-lg-offset-3 col-lg-6">
                <h3>百度一下</h3>
                <br />
                <div class="input-group">
                    <input type="text" class="form-control" id="word" placeholder="百度一下" aria-describedby="basic-addon2" /> 
                        <span class="input-group-addon btn" id="basic-addon2" style="background:#0078D7;font-color:white;">
                            <font color="white">百度一下</font>
                        </span>
                </div>
                <div id="data" style="width: 100%;height: 200px;display: none;padding-left:10px;">
                    <table id="tips" style="width: 100%;text-align: left;">

                    </table>
                </div>
            </div>
        </div>
    </div>
</body>
</html>
/**
 * 搜索的Servlet   SearchServlet.java
 */
public class SearchServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        try {
            // 获取要搜索关键字的参数
            String word = request.getParameter("word");
            // 调用业务层进行查询
            SearchService searchService = new SearchService();
            // 获取查询结果
            List<Word> list = searchService.queryWord(word);
            // 将数据转换为json格式
            JSONArray jsonArray = JSONArray.fromObject(list);

            // 设置response缓冲区的编码
            response.setCharacterEncoding("UTF-8");
            // 设置浏览器打开时的数据类型及编码格式
            response.setContentType("text/html;charset=UTF-8");
            // 将数据输出到客户端
            response.getWriter().println(jsonArray.toString());

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值