day040 ajax

本文探讨了两种常见场景:异步用户名校验,通过AJAX实时验证数据库中用户名的唯一性;以及自动填充功能,利用键盘弹起事件查询数据库并展示候选结果。通过jQuery和原生JS实现,涉及数据库操作和JSON数据处理。
摘要由CSDN通过智能技术生成

1 案例1-异步用户名校验

1.1 需求

当用户在输入框中填写完信息之后,光标离开输入框的时候,对用户输入的值进行校验,如果数据库中已经存在了这个值,则提示用户名已存在,否则提示可用。

1.2 技术分析

1:当页面加载的时候,给表单的输入框添加一个离焦事件。

2:当离焦事件触发的时候,获取表单项的值,并传递到servlet中,进行校验,提示结果。

(要求页面不能全部刷新,需要使用ajax技术完成)

1.3 Ajax概述

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML)

简单理解:

Ajax就是让浏览器在后台运行一个线程,自动与服务器进行数据交互,当服务器将数据响应回来之后,使用JavaScript对html的标签进行操作即可。

1.4 异步与同步的区别

同步:

浏览器时时与服务器进行数据交互,如果服务器没有处理完成,浏览器将一直等待,不能做其他的时候。

image.png

异步:

浏览器使用后台线程与服务器交互,用户可以在浏览器上进行多次其他的操作。

image.png

1.5 使用原生的js操作ajax(了解)

GET方式的步骤:

1:创建ajax引擎对象。(专门用于与服务器交互的对象)

2:编写一个回调函数。(指示ajax引擎对象当获取服务器的数据之后,做什么)

3:设置请求路径与参数。(告诉ajax引擎向哪个servlet发请求)

4:开始发送请求。(告诉ajax引擎,开始做事情)

POST方式的步骤:

1:创建ajax引擎对象。(专门用于与服务器交互的对象)

2:编写一个回调函数。(指示ajax引擎对象当获取服务器的数据之后,做什么)

3:设置请求路径与参数。(告诉ajax引擎向哪个servlet发请求)

4:设置请求头。(context-Type,值是form表单的默认值:)

5:开始发送请求。(告诉ajax引擎,开始做事情)

 

举例:

js_ajax.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">
<title>使用原生的js发ajax请求</title>
<script type="text/javascript">
    //发get请求方式的ajax
    function getAjax(){
        /*
        1:创建ajax引擎对象;(专门用于与服务器交互的对象)
        2:编写一个回调函数;(指示ajax引擎对象当获取服务器的数据之后,做什么)
        3:设置请求路径与参数;(告诉ajax引擎向哪个servlet发请求)
        4:开始发送请求;(告诉ajax引擎,开始做事情)
        */
        //1:创建ajax引擎对象;(专门用于与服务器交互的对象)
        var r = new XMLHttpRequest();
        //2:编写一个回调函数;(指示ajax引擎对象当获取服务器的数据之后,做什么)
        r.onreadystatechange=function(){
            //如果此时已经到达了最后的状态,且服务器响应回来的状态码是200;
            if(r.readyState==4&&r.status==200){
                //一切ok
                alert(r.responseText);
            }
        }
        //3:设置请求路径与参数;(告诉ajax引擎向哪个servlet发请求)
        r.open("GET","${pageContext.request.contextPath}/GetHello");
        //4:开始发送请求;(告诉ajax引擎,开始做事情)
        r.send();
    }
    //发post请求方式的ajax
    function postAjax(){
        /*
        1:创建ajax引擎对象;(专门用于与服务器交互的对象)
        2:编写一个回调函数;(指示ajax引擎对象当获取服务器的数据之后,做什么)
        3:设置请求路径与参数;(告诉ajax引擎向哪个servlet发请求)
        4:设置请求头;(context-Type,值是form表单的默认值:)
        5:开始发送请求;(告诉ajax引擎,开始做事情)
        */
        //1:创建ajax引擎对象;(专门用于与服务器交互的对象)
        var r = new XMLHttpRequest();
        //2:编写一个回调函数;(指示ajax引擎对象当获取服务器的数据之后,做什么)
        r.onreadystatechange=function(){
            //如果此时已经到达了最后的状态,且服务器响应回来的状态码是200;
            if(r.readyState==4&&r.status==200){
                //一切ok
                alert(r.responseText);
            }
        }
        //3:设置请求路径与参数;(告诉ajax引擎向哪个servlet发请求)
        r.open("POST","${pageContext.request.contextPath}/PostHello");
        //4:设置请求头;(context-Type,值是form表单的默认值:)
        r.setRequestHeader("Context-Type","application/x-www-form-urlencoded");
        //5:开始发送请求;(告诉ajax引擎,开始做事情)
        r.send();
    }
</script>
</head>
<body>
    <a href="javascript:getAjax()">发送get方式的ajax请求</a>
    <br>
    <a href="javascript:postAjax()">发送post方式的ajax请求</a>
</body>
</html>

GetHello.java

package com.itheima.demo01_Ajax;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 练习get方式的ajax请求
 */
public class GetHello extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //直接响应一句话
        response.getWriter().println("how Are you!!!");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

PostHello.java

package com.itheima.demo01_Ajax;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 练习原生js的post方式的ajax
 */
public class PostHello extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("postpostpost");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

1.6 Jquery中的ajax(重要)

在jquery中已经将js发送ajax请求的步骤封装成了一个方法,我们只需要调用jquery中的方法,即可完成ajax请求的动作。

Jquery中封装了3个关于ajax的方法:

1:ajax();    假如需要对服务器发生错误时,进行处理,可以使用这个方法。

2:get();     发送get请求。

3:post();     发送post请求。

get与post方法的参数有4个:

1:url路径。(必填)

2:参数。(可选的,格式:{参数名1:参数值1,参数名2:参数值2})

3:回调函数。(建议写,且回调函数有一个形参,形参代表的就是服务器响应回来的数据)

4:响应回来的数据类型。(可选的,只有获取json数据的时候才写,其他情况省略即可)

Get方法与post方法的参数与代码格式是一样的,仅仅是一个发get请求,另一个发post请求而已;

 

举例:

jquery_ajax.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 }/js/jquery-1.11.3.min.js"></script>
<title>jquery的ajax</title>
<script type="text/javascript">
    //发get请求
    function getAjax(){
        //直接调用方法即可
        $.get("${pageContext.request.contextPath }/JqueryGet",{"a":123,"sex":"man"},function(data){
            alert("欢迎回来:"+data);    
        });
    }
</script>

</head>
<body>
    <a href="javascript:getAjax()">发送get方式的ajax请求</a>
    <br>
    <a href="javascript:postAjax()">发送post方式的ajax请求</a>
</body>
</html>

JqueryGet.java

package com.itheima.demo01_Ajax;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * jquery方式发送get请求的ajax
 */
public class JqueryGet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        String p1 = request.getParameter("a");
        String p2 = request.getParameter("sex");
        response.getWriter().println(" 服务器响应的数据: "+p1+";"+p2);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

1.7 案例步骤分析

1:环境搭建;(创建3层包结构,复制jar包,静态页面等)

2:创建数据库与模型类;

3:编写jsp文件,包含一个表单,让用户输入用户名;(功能入口)

4:给输入框绑定一个离焦事件,当触发的时候,获取用户填写的名称,并使用ajax的方式发送给servlet进行检验,返回校验的结果;

5:编写servlet,service,dao查数据库;

2 案例2-异步自动填充

2.1 需求

当用户在输入框中填写信息的时候,获取用户填写的值并从数据库中查询包含这个值的所有字符串,显示在输入框下面,供用户参考选择使用。

2.2 技术分析

需要给输入框绑定一个键盘弹起事件,在事件触发的时候,获取输入框的值,并对输入框的值使用ajax方式进行传递,传给servlet,根据名称模糊查询相关的信息,会得到一个list集合。

为了让服务器和浏览器上的js都能识别这个集合中的数据,因此需要将list集合中的数据以json格式的形式进行传递。

2.3 JSON数据

采用完全独立于编程语言的文本格式来存储和表示数据。

Json只是一个数据格式,多种语言都可以识别这个数据格式。

通常用于网络中的数据传递。

2.4 JSON的数据格式

Json对象格式:

{属性名1:属性值1,属性名2:属性值2....}

Json数组对象格式:

[元素1,元素2....]

[{属性名1:属性值1,属性名2:属性值2....},{属性名1:属性值1,属性名2:属性值2....}....]

Json对象的取值格式:

var xxx = Json对象.属性名;

2.5 将java中的数据转成json格式的数据

在java中json格式的数据就是一个字符串。

将这个特殊格式的字符串响应给浏览器的时候,浏览器可以直接识别这个json格式的数据。

需要使用json-lib工具类,可以帮我们进行数据转换。

步骤:

1:下载并解压zip文件。(一共6个jar)

2:复制jar包到工程中。

3:使用核心类的静态方法,直接转换即可。

核心类:

JSONObject:其他任意对象或双列集合;

JSONArray:转换数组或单列集合;

静态方法:

fromObject(要转换的原始数据):会得到一个核心类对象。然后直接调用toString方法,即可获取一个字符串形式的json格式的数据。

 

举例:

import java.util.ArrayList;

import com.itheima.anli04_domain.Word;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class JSONTest {

    public static void main(String[] args) {
        //1:创建一个Word对象,并转成json格式的数据
        Word w = new Word(1,"jack");
        //2:使用核心类的静态方法直接转换即可
        String s = JSONObject.fromObject(w).toString();
        System.out.println(s);
        //3:转list集合
        ArrayList<Word> li = new ArrayList<Word>();
        li.add(new Word(1,"jack1"));
        li.add(new Word(2,"jack2"));
        li.add(new Word(3,"jack3"));
        //4:转成json
        String s2 = JSONArray.fromObject(li).toString();
        System.out.println(s2);
    }
}

// 打印结果
// {"id":1,"keyname":"jack"}
// [{"id":1,"keyname":"jack1"},{"id":2,"keyname":"jack2"},{"id":3,"keyname":"jack3"}]

2.6 案例步骤分析

1:环境搭建;(与第一个案例使用同一个环境)

2:使用同一个数据库;

3:在demo2.jsp页面中给输入框绑定一个键盘弹起事件;

4:当事件触发的时候,向servlet发送请求,携带用户当前填写的值,并根据这个值,模糊查询数据库中所有的相关记录,将相关记录的集合转成json数据并返回到浏览器页面;

5:在ajax的回调函数中,将json解析出来keyname的值,并添加到输入框下面的div中;

3 案例1与案例2的代码实现

数据库准备

/*
SQLyog Ultimate v12.08 (64 bit)
MySQL - 5.5.49 : Database - day40
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`day40` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `day40`;

/*Table structure for table `word` */

DROP TABLE IF EXISTS `word`;

CREATE TABLE `word` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `keyname` varchar(12) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;

/*Data for the table `word` */

insert  into `word`(`id`,`keyname`) values (1,'abstract'),(2,'boolean'),(3,'break'),(4,'byte'),(5,'case'),(6,'catch'),(7,'char'),(8,'class'),(9,'continue'),(10,'default'),(11,'do'),(12,'double'),(13,'else'),(14,'extends'),(15,'final'),(16,'finally'),(17,'for'),(18,'if'),(19,'implements'),(20,'instanceof'),(21,'long'),(22,'native'),(23,'package'),(24,'private'),(25,'protected'),(26,'public'),(27,'return'),(28,'short'),(29,'static'),(30,'super'),(31,'switch'),(32,'this'),(33,'transient'),(34,'try');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

项目结构

image.png

Word.java

package com.itheima.anli04_domain;

public class Word {
    private int id;
    private String keyname;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getKeyname() {
        return keyname;
    }
    public void setKeyname(String keyname) {
        this.keyname = keyname;
    }
    public Word(int id, String keyname) {
        super();
        this.id = id;
        this.keyname = keyname;
    }
    public Word() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Override
    public String toString() {
        return "Word [id=" + id + ", keyname=" + keyname + "]";
    }
}

 

demo1.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 }/js/jquery-1.11.3.min.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
    //当页面加载的时候,给name输入框绑定离焦事件
    $(function(){
        //选中name输入框绑定离焦事件
        $("input[name='username']").blur(function(){
            //当事件触发的时候,获取输入框的值,并发送ajax请求
            var v=$("input[name='username']").val();
            $.post("${pageContext.request.contextPath }/AnLi",{"m":"findCountByKeyname","name":v},function(d){
                //当ajax请求成功之后,d就是服务器响应回来的数据
                if(d==0){
                    //设置可用
                    $("#usename_msg").html('<font color="green">恭喜您,用户名可用!!!</font>');
                    //让注册按钮可用
                    $("#btn").attr("disabled",false);
                }else{
                    //设置不可用
                    $("#usename_msg").html('<font color="red">用户名已存在!!!</font>');
                    //禁用注册按钮
                    $("#btn").attr("disabled",true);
                }
            });
        });
    })
</script>
</head>
<body>
    <form method="post" action="#">
        <table>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="username"></td>
                <td><span id="usename_msg"></span></td>
            </tr>
            
            <tr>
                <td colspan='3'><input type="submit" value="注册" id="btn"></td>
            </tr>
        </table>
    </form>
</body>

</html>

demo2.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 }/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
    //1:当页面加载的时候,给输入框绑定一个键盘弹起事件
    $(function(){
        $("#tid").keyup(function(){
            //清除div中原始的信息
            $("#did").html("");
            //获取当前输入框的值
            var v=$("#tid").val();
            if(!v){
                $("#did").hide();
                return;
            }
            //alert(v)
            //向servlet发异步请求
            $.post("${pageContext.request.contextPath }/AnLi",{"m":"findJsonByKeyname","name":v},function(d){
                //此时的d就是服务器响应的json数据,是数组
                for(var i=0;i<d.length;i++){
                    //从json对象中获取keyname的值
                    var n=d[i].keyname;
                    //将这些值添加到隐藏的div中
                    $("#did").append('<div onmouseover="ru(this)" onmouseout="chu(this)" onclick="ji(this)">'+n+"</div>");
                    //让div显示出来
                    $("#did").show();
                }
            },"json");
        });
    })
    //鼠标移入的方法
    function ru(t){
        $(t).css("backgroundColor","red");
    }
    //鼠标移出的方法
    function chu(t){
        $(t).css("backgroundColor","white");
    }
    //鼠标点击的方法
    function ji(t){
        var text=$(t).html();
        $("#tid").val(text);
        $("#did").hide();
    }
</script>
<title>Insert title here</title>
</head>
<body>


    <center>
        <div>
            <h1>黑马搜索</h1>
            <div>
                <input name="kw" id="tid"><input type="button" value="黑马一下">
            </div>
            <div id="did" style="border: 1px solid red;width: 171px;position:relative;left:-34px;display:none"></div>
        </div> 
    </center>
</body>
</html>

AnLi.java

package com.itheima.anli01_servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.itheima.anli02_service.AnLiService;
import com.itheima.anli04_domain.Word;
import com.itheima.anli05_utils.MyBaseServlet;

import net.sf.json.JSONArray;

/**
 * 两个案例通用的servlet,直接继承MyBaseServlet,并编写相应的方法即可
 */
public class AnLi extends MyBaseServlet {
    //ajax请求,不用转发,直接响应数据即可
    public void findCountByKeyname(HttpServletRequest request, HttpServletResponse response) throws Exception {
        /*
         * 1:参
         * 2:调
         * 3:响应
         */
        String n = request.getParameter("name");
        AnLiService s = new AnLiService();
        int c=s.findCountByKeyname(n);
        response.getWriter().print(c);
    }
    //ajax请求,不用转发,直接响应数据即可    根据名称查询对象列表的方法
    public void findJsonByKeyname(HttpServletRequest request, HttpServletResponse response) throws Exception {
        /*
         * 1:参
         * 2:调
         * 3:将集合转成json
         * 4:响应 json字符串
         */
        String n = request.getParameter("name");
        AnLiService s = new AnLiService();
        List<Word> li =s.findJsonByKeyname(n);
        String js=JSONArray.fromObject(li).toString();
        response.getWriter().print(js);
    }
}

AnLiService.java

package com.itheima.anli02_service;

import java.sql.SQLException;
import java.util.List;

import com.itheima.anli03_dao.AnLiDao;
import com.itheima.anli04_domain.Word;

public class AnLiService {
    //1:根据名称查询记录数量的方法
    public int findCountByKeyname(String n) throws SQLException {
        return new AnLiDao().findCountByKeyname(n);
    }
    //2:根据名称查询对象列表的方法
    public List<Word> findJsonByKeyname(String n) throws SQLException {
        return new AnLiDao().findJsonByKeyname(n);
    }

}

AnLiDao.java

package com.itheima.anli03_dao;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.itheima.anli04_domain.Word;
import com.itheima.anli05_utils.MyC3P0Utils;

public class AnLiDao {
    //1:根据名称查询记录数量的方法
    public int findCountByKeyname(String n) throws SQLException {
        QueryRunner q = new QueryRunner(MyC3P0Utils.getDataSource());
        String sql = "select count(*) from word where keyname = ?";
        Long l = (Long)q.query(sql, new ScalarHandler(),n);
        return l.intValue();
    }
    //2:根据名称查询对象列表的方法
    public List<Word> findJsonByKeyname(String n) throws SQLException {
        QueryRunner q = new QueryRunner(MyC3P0Utils.getDataSource());
        String sql = "select * from word where keyname like ?";
        return q.query(sql, new BeanListHandler(Word.class),"%"+n+"%");
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值