(修订版)AJAX应用!

Ajax 简介 主流 Web 编程模式的历史实践和当前实践在过去几年,JavaScript 已从让人事后才想起的偶然对象变成最重要的 Web 语言。如果要指出一个推动这项技术显著进步的因素,那就是基于 Ajax 的应用程序开发的出现。简言之,Ajax 是一种开发技术和设计模式,支持网站或应用程序,使用实时数据更新界面,无需页面刷新。该功能创建了一种更为流畅且更具桌面风格的用户体验。Ajax 简史Ajax 的发展历史 阅读详情

前言

只有光头才能变强。

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

一、股票案例

我们要做的是股票的案例,它能够无刷新地更新股票的数据。当鼠标移动到具体的股票中,它会显示具体的信息。

我们首先来看一下要做出来的效果:

640?wx_fmt=gif
这里写图片描述

1.1服务器端分析

首先,从效果图我们可以看见很多股票基本信息:昨天收盘价、今天开盘价、最高价、最低价、当前价格、涨幅。这些信息我们用一个类来描述出来。

我们发现数据是定时刷新的,于是我们需要一个定时器。

服务器端的数据和客户端交互,我们使用JSON吧

1.2服务器端代码

1.2.1Stock股票类的代码

  private String id;  private String name;  private double yesterday;  private double today ;  private double highest;  private double lowest;  private double current;  private String range ;//各种setter和getter

  private String name;

  private double yesterday;

  private double today ;

  private double highest;

  private double lowest;

  private double current;

  private String range ;

//各种setter和getter
/** * id,name,yesterday这三个参数都是固定的,其他的属性都是可变的。 * 因此我们构造函数就传入这三个值 * */public Stock(String id, String name, double yesterday) {    this.id = id;    this.name = name;    this.yesterday = yesterday;    //把开盘价设定为-1,后面在定时器计算出来的随机数,如果发现开盘价是-1,就设置第一次的随机数为开盘价    this.today = -1;    //把最高、最低、当前的价格都暂且设置成昨天的开盘价,后面我们可以变化的    this.highest = yesterday;    this.current = yesterday;    this.lowest = yesterday;}
public Stock(String id, String name, double yesterday) {
    this.id = id;
    this.name = name;
    this.yesterday = yesterday;

    //把开盘价设定为-1,后面在定时器计算出来的随机数,如果发现开盘价是-1,就设置第一次的随机数为开盘价
    this.today = -1;

    //把最高、最低、当前的价格都暂且设置成昨天的开盘价,后面我们可以变化的
    this.highest = yesterday;
    this.current = yesterday;
    this.lowest = yesterday;

}
/** * 每次设置当前价钱的时候,最高、最低、涨幅都应该随着当前价钱而变化的 */public void setCurrent(double current) {    //计算出涨幅或跌幅    double range = (current - this.yesterday) / this.yesterday;    //设置涨幅和跌幅不能超过10%,当前的价格只能是昨天开盘价的1.1倍或0.9倍    //当前价格应该是两位小数    DecimalFormat formatPrice = new DecimalFormat("#.00");    if (range > 0.1) {        current = Double.parseDouble(formatPrice.format(this.yesterday * 1.1));    }    if (range < -0.1) {        current = Double.parseDouble(formatPrice.format(this.yesterday * 0.9));    }    this.current = current;    //如果今天开盘价没设定,那么就将第一次的当前价作为今天的开盘价    if (this.today == -1) {        this.today = this.current;    }    //比较最大值和最小值    if (this.current > this.highest) {        this.highest = this.current;    }    if (this.current < this.lowest) {        this.lowest = this.current;    }    //格式化涨幅的字符串,整数两位,小数两位    DecimalFormat formatRange = new DecimalFormat("##.##%");    this.range = formatRange.format(range);    }
public void setCurrent(double current) {

    //计算出涨幅或跌幅
    double range = (current - this.yesterday) / this.yesterday;

    //设置涨幅和跌幅不能超过10%,当前的价格只能是昨天开盘价的1.1倍或0.9倍

    //当前价格应该是两位小数
    DecimalFormat formatPrice = new DecimalFormat("#.00");

    if (range > 0.1) {
        current = Double.parseDouble(formatPrice.format(this.yesterday * 1.1));
    }

    if (range < -0.1) {
        current = Double.parseDouble(formatPrice.format(this.yesterday * 0.9));
    }
    this.current = current;

    //如果今天开盘价没设定,那么就将第一次的当前价作为今天的开盘价
    if (this.today == -1) {
        this.today = this.current;
    }

    //比较最大值和最小值
    if (this.current > this.highest) {
        this.highest = this.current;
    }
    if (this.current < this.lowest) {
        this.lowest = this.current;
    }

    //格式化涨幅的字符串,整数两位,小数两位
    DecimalFormat formatRange = new DecimalFormat("##.##%");
    this.range = formatRange.format(range);    
}

1.2.2Servlet的代码

/** * 重写init()方法,加入一些配置内容 */@Overridepublic void init(ServletConfig config) throws ServletException {    map = new HashMap<>();    //新建几只固定的股票    final Stock zhong = new Stock("1", "百度", 1110.1);    final Stock fu = new Stock("2", "阿里", 222.2);    final Stock cheng = new Stock("3", "腾讯", 333.3);    final Stock ou = new Stock("4", "谷歌", 1133.5);    //添加到容器中    map.put("1", zhong);    map.put("2", fu);    map.put("3", cheng);    map.put("4", ou);    //生成随机数    final Random random = new Random();    //格式化生成的随机数    final DecimalFormat format = new DecimalFormat("#.00");    //Servlet被启动后1秒开始,每两秒扫描一次    timer = new Timer();    timer.schedule(new TimerTask() {        @Override        public void run() {            double baidu = random.nextDouble() * 1.1;            double ali = random.nextDouble() * 2;            double tengxun = random.nextDouble() * 0.3;            double geogle = random.nextDouble() * 4;            //概率大致都是50%,我们用来做正负            if (random.nextBoolean()) {                baidu = 0 - baidu;            }            if (random.nextBoolean()) {                ali = 0 - ali;            }            if (random.nextBoolean()) {                tengxun = 0 - tengxun;            }            if (random.nextBoolean()) {                geogle = 0 - geogle;            }            //设置它们的当前价格            zhong.setCurrent(Double.parseDouble(format.format(zhong.getCurrent()+baidu)));            fu.setCurrent(Double.parseDouble(format.format(fu.getCurrent()+ali)));            cheng.setCurrent(Double.parseDouble(format.format(cheng.getCurrent()+tengxun)));            ou.setCurrent(Double.parseDouble(format.format(ou.getCurrent()+geogle)));        }    }, 1000, 2000);}
@Override
public void init(ServletConfig config) throws ServletException {

    map = new HashMap<>();

    //新建几只固定的股票
    final Stock zhong = new Stock("1", "百度", 1110.1);
    final Stock fu = new Stock("2", "阿里", 222.2);
    final Stock cheng = new Stock("3", "腾讯", 333.3);
    final Stock ou = new Stock("4", "谷歌", 1133.5);

    //添加到容器中
    map.put("1", zhong);
    map.put("2", fu);
    map.put("3", cheng);
    map.put("4", ou);

    //生成随机数
    final Random random = new Random();

    //格式化生成的随机数
    final DecimalFormat format = new DecimalFormat("#.00");

    //Servlet被启动后1秒开始,每两秒扫描一次

    timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {

            double baidu = random.nextDouble() * 1.1;
            double ali = random.nextDouble() * 2;
            double tengxun = random.nextDouble() * 0.3;
            double geogle = random.nextDouble() * 4;

            //概率大致都是50%,我们用来做正负
            if (random.nextBoolean()) {
                baidu = 0 - baidu;
            }
            if (random.nextBoolean()) {
                ali = 0 - ali;
            }

            if (random.nextBoolean()) {
                tengxun = 0 - tengxun;
            }
            if (random.nextBoolean()) {
                geogle = 0 - geogle;
            }

            //设置它们的当前价格
            zhong.setCurrent(Double.parseDouble(format.format(zhong.getCurrent()+baidu)));
            fu.setCurrent(Double.parseDouble(format.format(fu.getCurrent()+ali)));
            cheng.setCurrent(Double.parseDouble(format.format(cheng.getCurrent()+tengxun)));
            ou.setCurrent(Double.parseDouble(format.format(ou.getCurrent()+geogle)));

        }
    }, 1000, 2000);


}
<servlet>    <servlet-name>Refresh</servlet-name>    <servlet-class>Refresh</servlet-class>    <load-on-startup>1</load-on-startup></servlet><servlet-mapping>    <servlet-name>Refresh</servlet-name>    <url-pattern>/Refresh</url-pattern></servlet-mapping>
    <servlet-name>Refresh</servlet-name>
    <servlet-class>Refresh</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Refresh</servlet-name>
    <url-pattern>/Refresh</url-pattern>
</servlet-mapping>
//封装成JSON格式,返回给浏览器StringBuffer buffer = new StringBuffer();//这里我们拼接成4个对象buffer.append("({");for (Map.Entry<String, Stock> entry : map.entrySet()) {    String id = entry.getKey();    Stock stock = entry.getValue();    buffer.append(id).append(":{yesterday:").append(stock.getYesterday()).append(",today:").append(stock.getToday()).append(",high:").append(stock.getHighest()).append(",low:").append(stock.getLowest()).append(",current:").append(stock.getCurrent()).append(",range:'").append(stock.getRange()).append("'}").append(",");}//消除最后一个逗号buffer.deleteCharAt(buffer.lastIndexOf(","));//最后补上括号buffer.append("})");//返回给浏览器response.getWriter().write(buffer.toString());
StringBuffer buffer = new StringBuffer();


//这里我们拼接成4个对象
buffer.append("({");
for (Map.Entry<String, Stock> entry : map.entrySet()) {
    String id = entry.getKey();
    Stock stock = entry.getValue();

    buffer.append(id).append(":{yesterday:").append(stock.getYesterday()).append(",today:").append(stock.getToday()).append(",high:").append(stock.getHighest()).append(",low:").append(stock.getLowest()).append(",current:").append(stock.getCurrent()).append(",range:'").append(stock.getRange()).append("'}").append(",");

}
//消除最后一个逗号
buffer.deleteCharAt(buffer.lastIndexOf(","));

//最后补上括号
buffer.append("})");

//返回给浏览器
response.getWriter().write(buffer.toString());
({  3:{yesterday:333.3,today:333.48,high:333.48,low:333.3,current:333.48,range:'0.05%'},  2:{yesterday:222.2,today:223.46,high:223.46,low:222.2,current:223.46,range:'0.57%'},  1:{yesterday:1110.1,today:1109.73,high:1110.1,low:1109.73,current:1109.73,range:'-0.03%'},  4:{yesterday:1133.5,today:1135.49,high:1135.49,low:1133.5,current:1135.49,range:'0.18%'}})3:{yesterday:333.3,today:333.48,high:333.48,low:333.3,current:333.48,range:'0.05%'},
  2:{yesterday:222.2,today:223.46,high:223.46,low:222.2,current:223.46,range:'0.57%'},
  1:{yesterday:1110.1,today:1109.73,high:1110.1,low:1109.73,current:1109.73,range:'-0.03%'},
  4:{yesterday:1133.5,today:1135.49,high:1135.49,low:1133.5,current:1135.49,range:'0.18%'}
})

1.3客户端分析之一

客户端要做的就是显示数据,每隔两秒就和服务器进行一次交互

1.3.1html代码

使用div嵌套span和a标签来进行显示,span装载的就是服务端返回json的current数据

<body onload="show()"><div>    <a href="#">百度:</a>    <span id="1"></span></div><div>    <a href="#">阿里巴巴:</a>    <span id="2"></span></div><div>    <a href="#">腾讯:</a>    <span id="3"></span></div><div>    <a href="#">谷歌:</a>    <span id="4"></span></div></body>

<div>
    <a href="#">百度:</a>
    <span id="1"></span>
</div>
<div>
    <a href="#">阿里巴巴:</a>
    <span id="2"></span>
</div>
<div>
    <a href="#">腾讯:</a>
    <span id="3"></span>
</div>
<div>
    <a href="#">谷歌:</a>
    <span id="4"></span>
</div>


</body>

1.3.2javaScript代码

function show() {    getStock();    //每两秒就取一次数据    setInterval(getStock, 2000);}var httpRequest;function getStock() {//力求是最新的响应数据,如果存在httpRequest,那么将上次的httpRequest终止    if(httpRequest) {        httpRequest.abort();    }    httpRequest= new XMLHttpRequest();    httpRequest.open("GET", "Refresh", true);    httpRequest.onreadystatechange = callBackFunction;    httpRequest.send(null);}function callBackFunction() {    if(httpRequest.readyState==4) {        if(httpRequest.status==200) {            //得到服务器端返回的JSON数据            var text = httpRequest.responseText;            //解析成JavaScript对象            var json = eval(text);            //遍历出每个JSON对象【也就是json的id】            for(var id in json) {                //得到每个stock对象                var stock = json[id];                //将当前的价格设置到span节点里面                document.getElementById(id).innerHTML = stock.current;                //比较当前价格和昨天开盘价格,如果大于就是红色,小于就是绿色                if(stock.current>stock.yesterday) {                    document.getElementById(id).style.color = 'red';                }else {                    document.getElementById(id).style.color = 'green';                }            }        }    }}

    getStock();

    //每两秒就取一次数据
    setInterval(getStock, 2000);

}
var httpRequest;
function getStock() {

//力求是最新的响应数据,如果存在httpRequest,那么将上次的httpRequest终止
    if(httpRequest) {
        httpRequest.abort();
    }

    httpRequest= new XMLHttpRequest();
    httpRequest.open("GET", "Refresh", true);
    httpRequest.onreadystatechange = callBackFunction;
    httpRequest.send(null);

}

function callBackFunction() {
    if(httpRequest.readyState==4) {
        if(httpRequest.status==200) {

            //得到服务器端返回的JSON数据
            var text = httpRequest.responseText;

            //解析成JavaScript对象
            var json = eval(text);

            //遍历出每个JSON对象【也就是json的id】
            for(var id in json) {

                //得到每个stock对象
                var stock = json[id];

                //将当前的价格设置到span节点里面
                document.getElementById(id).innerHTML = stock.current;

                //比较当前价格和昨天开盘价格,如果大于就是红色,小于就是绿色
                if(stock.current>stock.yesterday) {
                    document.getElementById(id).style.color = 'red';
                }else {
                    document.getElementById(id).style.color = 'green';

                }
            }

        }
    }
}
640?wx_fmt=gif
这里写图片描述

1.4客户端分析之二

当鼠标移动到具体的股票超链接的时候,会显示具体的数据,并且数据是动态的

1.4.1html代码:

绑定事件,只要鼠标移动到超链接上就触发事件

<body onload="show()"><div>    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">百度:</a>    <span id="1"></span></div><div>    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">阿里巴巴:</a>    <span id="2"></span></div><div>    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">腾讯:</a>    <span id="3"></span></div><div>    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">谷歌:</a>    <span id="4"></span></div><div id="toolTip">    <div>        昨收:<span id="yesterday"></span>    </div>    <div>        今收:<span id="today"></span>    </div>    <div>        最低:<span id="low"></span>    </div>    <div>        当前:<span id="current"></span>    </div>    <div>        最高:<span id="high"></span>    </div>    <div>        涨幅:<span id="range"></span>    </div></div></body>

<div>
    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">百度:</a>
    <span id="1"></span>
</div>
<div>
    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">阿里巴巴:</a>
    <span id="2"></span>
</div>
<div>
    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">腾讯:</a>
    <span id="3"></span>
</div>
<div>
    <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">谷歌:</a>
    <span id="4"></span>
</div>

<div id="toolTip">
    <div>
        昨收:<span id="yesterday"></span>
    </div>

    <div>
        今收:<span id="today"></span>
    </div>

    <div>
        最低:<span id="low"></span>
    </div>
    <div>
        当前:<span id="current"></span>
    </div>
    <div>
        最高:<span id="high"></span>
    </div>
    <div>
        涨幅:<span id="range"></span>
    </div>
</div>


</body>

1.4.2css代码

详细框的信息默认是隐藏的

<style type="text/css">    #toolTip {        border: 1px solid #000;        width: 150px;        position: absolute;        display: none;    }</style>type="text/css">

    #toolTip {
        border: 1px solid #000;
        width: 150px;
        position: absolute;
        display: none;
    }

</style>

1.4.3javaScript代码

得到交互的数据,设置span里面的值

function update() {    var stock = json[sid];    //得到相对应的控件    var yesterday = document.getElementById("yesterday");    var today = document.getElementById("today");    var low = document.getElementById("low");    var high = document.getElementById("high");    var range = document.getElementById("range");    var current = document.getElementById("current");    //设置具体信息的值    high.innerHTML = stock.high;    range.innerHTML = stock.range;    current.innerHTML = stock.current;    yesterday.innerHTML = stock.yesterday;    today.innerHTML = stock.today;    low.innerHTML = stock.low;    //如果数值比昨天开盘价低,反则就是红色    if (stock.today > stock.yesterday) {        today.style.color = 'red';    } else {        today.style.color = 'green';    }    if (stock.low > stock.yesterday) {        low.style.color = 'red';    } else {        low.style.color = 'green';    }    if (stock.high > stock.yesterday) {        high.style.color = 'red';    } else {        high.style.color = 'green';    }    //如果现在的价格比昨天开盘高,那么涨幅是红色    if (stock.current > stock.yesterday) {        range.style.color = 'red';        current.style.color = 'red';    } else {        range.style.color = 'green';        current.style.color = 'green';    }}

    var stock = json[sid];

    //得到相对应的控件
    var yesterday = document.getElementById("yesterday");
    var today = document.getElementById("today");
    var low = document.getElementById("low");
    var high = document.getElementById("high");
    var range = document.getElementById("range");
    var current = document.getElementById("current");

    //设置具体信息的值

    high.innerHTML = stock.high;
    range.innerHTML = stock.range;
    current.innerHTML = stock.current;
    yesterday.innerHTML = stock.yesterday;
    today.innerHTML = stock.today;
    low.innerHTML = stock.low;

    //如果数值比昨天开盘价低,反则就是红色
    if (stock.today > stock.yesterday) {
        today.style.color = 'red';
    } else {
        today.style.color = 'green';
    }

    if (stock.low > stock.yesterday) {
        low.style.color = 'red';
    } else {
        low.style.color = 'green';
    }
    if (stock.high > stock.yesterday) {
        high.style.color = 'red';
    } else {
        high.style.color = 'green';
    }

    //如果现在的价格比昨天开盘高,那么涨幅是红色
    if (stock.current > stock.yesterday) {
        range.style.color = 'red';
        current.style.color = 'red';
    } else {
        range.style.color = 'green';
        current.style.color = 'green';
    }
}

只有鼠标移到超链接上,才明确id的值是多少!

function callBackFunction() {    if (httpRequest.readyState == 4) {        if (httpRequest.status == 200) {            //得到服务器端返回的JSON数据            json= eval(httpRequest.responseText);            //更新详细框的数据,当鼠标移动到超链接上才确定有id,于是判断有没有id            if(sid) {                update();            }            //遍历出每个JSON对象【也就是json的id】            for (var id in json) {                //得到每个stock对象                var stock = json[id];                //将当前的价格设置到span节点里面                document.getElementById(id).innerHTML = stock.current;                //比较当前价格和昨天开盘价格,如果大于就是红色,小于就是绿色                if (stock.current > stock.yesterday) {                    document.getElementById(id).style.color = 'red';                } else {                    document.getElementById(id).style.color = 'green';                }            }        }    }}function showTool(node) {    //得到鼠标移动到具体股票的id    sid = node.parentNode.getElementsByTagName("span")[0].id;    //把详细框框显示出来    document.getElementById("toolTip").style.display = 'block';}function clearTool() {    document.getElementById("toolTip").style.display = 'none';}
    if (httpRequest.readyState == 4) {
        if (httpRequest.status == 200) {

            //得到服务器端返回的JSON数据
            json= eval(httpRequest.responseText);

            //更新详细框的数据,当鼠标移动到超链接上才确定有id,于是判断有没有id
            if(sid) {
                update();
            }

            //遍历出每个JSON对象【也就是json的id】
            for (var id in json) {

                //得到每个stock对象
                var stock = json[id];

                //将当前的价格设置到span节点里面
                document.getElementById(id).innerHTML = stock.current;

                //比较当前价格和昨天开盘价格,如果大于就是红色,小于就是绿色
                if (stock.current > stock.yesterday) {
                    document.getElementById(id).style.color = 'red';
                } else {
                    document.getElementById(id).style.color = 'green';

                }
            }


        }
    }
}

function showTool(node) {

    //得到鼠标移动到具体股票的id
    sid = node.parentNode.getElementsByTagName("span")[0].id;

    //把详细框框显示出来
    document.getElementById("toolTip").style.display = 'block';

}
function clearTool() {
    document.getElementById("toolTip").style.display = 'none';
}

1.5最终效果:

640?wx_fmt=gif
这里写图片描述

1.6总结要点

①:这是由AJAX来实现的,因为它无刷新的动态交互数据。

②:服务器端应该保存着股票的基本信息。于是乎,我们用一个类来装载着这些信息【信息之间的关系就不一一说明了,因为每个案例用的可能都不一样】

③:用到了DecimalFormat类来格式化小数变为自己想要的格式

④:使用HashMap来装载这些股票,使用Map集合主要是在客户端中,可以通过键来访问具体的股票,只要能访问到股票了,那么一切就好说了。

⑤:当然啦,装载股票的任务就交给init()方法,因为只需要装载一次。

⑥:我们会发现,股票的信息是不断会变化的,所以我们使用定时器和Random类来不断修改股票的信息

⑦:JavaScript和服务端交互使用AJAX,要么使用XML,要么就是JSON,这次我们采用的是JSON

⑧:JavaScript使用XMLHttpRequest对象得到Servlet返回给浏览器的JSON数据,解析JSON数据,变成是JavaScript对象

⑨:在页面上显示服务端带过来的数据,一般都是使用div来显示【块级】,用控件绑定id,在JavaScript中得到控件,填充数据。这样就是动态地修改页面的数据了。

⑩:浏览器想要不断地从服务端获取股票的数据,那么就需要不断地与服务端交互,解析JSON,填充数据…..这种我们可以通过setInterval()定时器来做

①①:想要修改字体的颜色,只要获取它的控件再style.color就可以修改了。

①②:鼠标移动到具体的股票链接的时候,会出现股票的详细信息时,这明显就是为超链接绑定了事件

①③:股票的详细信息用一个框框装载着,那么我们就在css中初始化这个框框,它平时是不显示出来的,只用在鼠标移到它那里的时候才显示,我们把display=“none”就行了。

①④:在响应事件的时候,我们需要知道用户是移动到哪一个超链接上,所以要获取得到具体的超链接id。知道id以后,我们就知道用户想要知道的股票是哪一个了。

①⑤:股票的信息也想要及时的更新,那么我们想把它抽取成一个方法,在AJAX回调方法中加入进去就行了。当然了,id和具体股票对象应该是全局的变量【这样才能够在别的方法中用到】

二、验证码校验

对于验证码检查我们并不会陌生,我们在学习Session的时候已经使用过了验证码检查了。详细可参考:http://blog.youkuaiyun.com/hon_3y/article/details/54799494#t11

我们当时是同步检查验证码是否正确的,其实没有必要。因为就验证一个输入框的数据,没必要使用同步的方式验证【使用异步对用户体验更加友好】

640?wx_fmt=jpeg
a

2.1分析

当用户输入完4位数字的时候,就去服务器端验证是否需要相同,如果相同,那么返回一个打钩的图片。如果不同,那么就返回一个打叉的图片

2.1.1前台分析

2.1.2后台分析


2.2编写JSP

值得注意的是:要获取td定义的id,外边一定要套上table标签。。。我在刚开始写的时候,是没有table标签的。然后死活得不到td的标签….很烦…

<%--  Created by IntelliJ IDEA.  User: ozc  Date: 2017/5/17  Time: 20:52  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>验证码校验</title>    <script type="text/javascript" src="js/ajax.js"></script></head><body><%--###################展示页面#############################--%><table>    <tr>        <td>验证码:</td>        <td><input type="text" id="checkCode" name="checkCode"></td>        <td><img src="01_image.jsp"/></td>        <td id="result"></td>    </tr></table><%--###################去除空格方法#############################--%><script type="text/javascript">    function trim(str) {        //去除左边的空格        str.replace("/^\s*/", "");        //去除右边的空格        str.replace("/\s*$/", "");        return str;    }</script><%--###################绑定键盘事件#############################--%><script type="text/javascript">    document.getElementById("checkCode").onkeyup = function () {        //得到输入框的内容,把的前后空格都去除        var keyValue = this.value;        keyValue = trim(keyValue);        /*******************ajax代码*******************************/        if (keyValue.length == 4) {            var ajax = createAJAX();            var method = "post";            var url = "${pageContext.request.contextPath}/CheckCodeServlet?time=" + new Date().getTime();            ajax.open(method, url);            ajax.setRequestHeader("content-type", "application/x-www-form-urlencoded");            ajax.send("keyValue=" + keyValue);            /*******************ajax回调函数*******************************/            ajax.onreadystatechange = function () {                if (ajax.readyState == 4) {                    if (ajax.status == 200) {                        //得到服务器带过来的数据                        var tip = ajax.responseText;                        /*******************使用DOM把数据添加到页面上*******************************/                        var img = document.createElement("img");                        img.src = tip;                        img.style.width = "14px";                        img.style.height = "14px";                        var td = document.getElementById("result");                        td.innerHTML = "";                        td.appendChild(img);                    }                }            };        }else {            //清空图片            var td = document.getElementById("result");            td.innerHTML = "";        }    };</script></body></html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>验证码校验</title>
    <script type="text/javascript" src="js/ajax.js"></script>
</head>
<body>


<%--###################展示页面#############################--%>

<table>
    <tr>
        <td>验证码:</td>
        <td><input type="text" id="checkCode" name="checkCode"></td>
        <td><img src="01_image.jsp"/></td>
        <td id="result"></td>
    </tr>
</table>


<%--###################去除空格方法#############################--%>
<script type="text/javascript">

    function trim(str) {

        //去除左边的空格
        str.replace("/^\s*/", "");

        //去除右边的空格
        str.replace("/\s*$/", "");
        return str;

    }
</script>


<%--###################绑定键盘事件#############################--%>

<script type="text/javascript">


    document.getElementById("checkCode").onkeyup = function () {

        //得到输入框的内容,把的前后空格都去除
        var keyValue = this.value;
        keyValue = trim(keyValue);

        /*******************ajax代码*******************************/
        if (keyValue.length == 4) {


            var ajax = createAJAX();
            var method = "post";
            var url = "${pageContext.request.contextPath}/CheckCodeServlet?time=" + new Date().getTime();
            ajax.open(method, url);
            ajax.setRequestHeader("content-type", "application/x-www-form-urlencoded");
            ajax.send("keyValue=" + keyValue);


            /*******************ajax回调函数*******************************/
            ajax.onreadystatechange = function () {
                if (ajax.readyState == 4) {
                    if (ajax.status == 200) {

                        //得到服务器带过来的数据
                        var tip = ajax.responseText;

                        /*******************使用DOM把数据添加到页面上*******************************/
                        var img = document.createElement("img");
                        img.src = tip;
                        img.style.width = "14px";
                        img.style.height = "14px";
                        var td = document.getElementById("result");
                        td.innerHTML = "";
                        td.appendChild(img);
                    }
                }
            };


        }else {
            //清空图片
            var td = document.getElementById("result");
            td.innerHTML = "";
        }


    };


</script>


</body>
</html>
import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** * Created by ozc on 2017/5/17. */@WebServlet(name = "CheckCodeServlet",urlPatterns = "/CheckCodeServlet")public class CheckCodeServlet extends HttpServlet {    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //得到带过来的数据        String keyValue = request.getParameter("keyValue");        //得到Session中的数据        String checkCodeInSession = (String) request.getSession().getAttribute("CHECKNUM");        response.setContentType("text/html;charset=UTF-8");        String src = "images/MsgError.gif";        //判断俩数据是否相同        if (keyValue.equals(checkCodeInSession)) {            src = "images/MsgSent.gif";        }        PrintWriter writer = response.getWriter();        writer.write(src);        writer.flush();        writer.close();    }    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        this.doPost(request, response);    }}
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Created by ozc on 2017/5/17.
 */

@WebServlet(name = "CheckCodeServlet",urlPatterns = "/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //得到带过来的数据
        String keyValue = request.getParameter("keyValue");
        //得到Session中的数据
        String checkCodeInSession = (String) request.getSession().getAttribute("CHECKNUM");
        response.setContentType("text/html;charset=UTF-8");

        String src = "images/MsgError.gif";

        //判断俩数据是否相同
        if (keyValue.equals(checkCodeInSession)) {
            src = "images/MsgSent.gif";
        }
        PrintWriter writer = response.getWriter();
        writer.write(src);

        writer.flush();
        writer.close();


    }

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

        this.doPost(request, response);

    }
}

2.3测试

640?wx_fmt=gif
这里写图片描述

2.4总结

最后

乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!

640?wx_fmt=jpeg

有帮助?在看!转发!640


第十九届全国大学生智能车竞赛越野信标 硬件篇 全国大学生智能汽车竞赛,越野信标组 阅读详情

相关推荐

AD56XXR系列DAC驱动设计:SPI接口、寄存器配置与嵌入式工程实践

数模转换器(DAC)是嵌入式系统实现高精度模拟控制的核心器件,其性能取决于通信协议可靠性、寄存器配置准确性及硬件协同设计能力。基于SPI总线的电压输出型DAC广泛应用于工业控制、光模块偏置、传感器校准等场景,需兼顾静态精度、动态响应与低功耗特性。AD56XXR系列作为典型集成内部基准与多通道同步更新能力的12/14/16位DAC,支持轨到轨输出与灵活掉电模式,为资源受限MCU提供可移植固件范式。本文围绕SPI时序约束、16位指令字解析、LDAC同步机制及精度补偿策略展开,覆盖从硬件连接、初始化流程到量产级可

weixin_33481022的博客 610

(修订版)AJAX入门!

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y一、什么是AjaxAjax(...

3y 504

单窗算法的地表温度反演:谷歌地球引擎GEE代码

该论文基于Statistical Mono-Window(SMW)算法,对地表温度加以求解。其中,简单地说,SMW算法即是通过简单的线性关系,对由单热红外波段所得的大气表观亮温与地表温度之间的经验关系加以表示,从而计算得到LST。

2301_78834737的博客 556

AJAX常见面试题(修订版)

前言 只有光头才能变强。 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y AJAX常见面试题 什么是AJAX,为什么要使用Ajax AJAX是“Asynchronous JavaScript and XML”的缩写。他是指一种创建交互式网页应用的网页开发技术。、 客户端与服务器,可以在【不必刷新整个浏览器】的情况下,与服务器进行异步通讯的技术 AJAX应用和传统Web应用有什么不同? AJAX应用和传统Web应用

feelinghappy的专栏 2685

我用 AI 做了个开源地图工具:从 OpenStreetMap 一键获取全国 AOI/POI 数据

本文介绍了一款免费开源的OSM数据查询与可视化工具,旨在解决Overpass QL语法晦涩、数据获取门槛高的问题。工具支持面数据(AOI)、点数据(POI)及路网三种查询模式,内置30+常用模板实现一键检索。具备高德与OSM双底图切换、坐标自动转换功能,支持GeoJSON、SHP、CSV多格式导出,同时保留自定义查询能力。作为纯HTML单文件应用,可零成本部署至GitHub Pages在线使用。该工具有效降低了地理数据获取难度,是替代商业地图API、高效提取全球开源地理信息的实用利器。

weixin_45812624的博客 587

Unity UGUI高斯模糊背景效果 简易解决方案

UnityUI背景模糊效果简易解决方案1.功能描述简易界面框架搭建合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 1.功能描述 在我们玩游戏的时候,经常会看到一些游戏会对UI做这样的处理: 可以看到,新开的上层UI界面会以下层UI界面的模糊

SaberZG的博客 1万+

ajax servlet怎么接收_AJAX常见面试题(修订版)

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3yAJAX常见面试题什么是AJAX,为什么要使用AjaxAJAX是“Asynchronous JavaScript and XML”的缩写。他是指一种创建交互式网页应用的网页开发技术。、客户端与服务器,可以在【不必刷新整个浏览器】的情况下,与服务器进...

weixin_39662142的博客 177

快速入门必看!RT-DETR手把手训练自己的数据集去跑实验,基于 ultralytics 仓库源码改进,配置虚拟环境,准备数据集、训练、验证、推理测试 ,实现0到1的完整教学过程。

本文介绍了使用Ultralytics框架训练RT-DETR模型的全流程。首先需要创建Python 3.10虚拟环境,安装指定版本的PyTorch和相关依赖包。然后准备数据集,修改配置文件,并详细介绍训练、验证和推理三个核心步骤的代码实现。训练阶段使用RTDETR类加载模型配置,设置训练参数;验证阶段评估模型性能;推理阶段可对图片、视频等进行预测。文中还提供了清华大学镜像源加速下载,以及详细的参数配置说明,帮助用户快速搭建RT-DETR目标检测模型。

Ai缝合怪、助力小伙伴高效发论文 5560

ajax jq 图片上传请求头_(修订版)AJAX入门!

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y一、什么是AjaxAjax(Asynchronous JavaScript and XML) 异步JavaScript和XMLAjax实际上是下面这几种技术的融合:(1)XHTML和CSS的基于标准的表示技术 (2)DOM进行动态显示和交互 (3)...

weixin_36074359的博客 108

单片机原理及应用知识点汇总(一)

在键闭合稳定时,读取键的状态,并且必须判别;、串行通信的优点是只需一对传送线,成本低,适于远距离通信,缺点是传送速度较低。、并行通信的优点是传送速度高,缺点是所需传送线较多,远距离通信不方便。、串行通信中,为使设备同步工作,需要通信双方有两个共同的要求,一是。系列单片机的指令中,既有带借位的减法指令,又有不带借位的减法指令。、简述在使用普通按键的时候,为什么要进行去抖动处理,如何处理。、在异步通信的帧格式中,数据位是低位在前高位在后的排列方式。、异步通信中,波特率是指每秒传送二进制代码的位数,单位是。

T19900的博客 696

飞牛fnNAS虚拟机标准安装

飞牛NAS是一款基于Debian开发的国产免费NAS系统,支持x86架构设备,可将闲置硬件改造为NAS服务器。系统安装简便,支持多种存储模式与硬盘休眠功能,具备智能影视管理、照片备份等实用功能,并提供多种远程访问方式。飞牛NAS还支持Docker扩展,目前已承诺永久免费。文章详细介绍了在VMware虚拟机中安装飞牛NAS的步骤,包括下载镜像、创建虚拟机、初始化设置等过程,并展示了创建共享文件夹等基本操作,帮助用户快速上手这款功能强大的免费NAS系统。

dgnankai的专栏 3258

前端ajax数据提交到服务器_(修订版)AJAX入门!

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y一、什么是AjaxAjax(Asynchronous JavaScript and XML) 异步JavaScript和XMLAjax实际上是下面这几种技术的融合:(1)XHTML和CSS的基于标准的表示技术 (2)DOM进行动态显示和交互 (3)...

weixin_39930557的博客 171

Python 爬虫实战:手机应用商店评论数据爬取与分析

移动应用市场蓬勃发展,用户的评论数据包含了大量有价值的信息,如用户满意度、功能反馈、改进建议等。通过分析这些评论,我们可以挖掘应用的优缺点,甚至预测用户趋势。由于 Apple App Store 评论是动态加载的,我们使用。本篇博客将详细介绍如何使用 Python 爬取。爬取大量数据时,可能会遇到反爬机制。库获取 Google Play 评论。评论数据是动态加载的,需要使用。

2201_76125261的博客 2323

AJAX跨域完全讲解(修订版)

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3yAJAX跨域完全讲解我在收集...

3y 365

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

只有ajax会跨域吗_AJAX跨域完全讲解(修订版)

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3yAJAX跨域完全讲解我在收集AJAX面试题的时候其实就已经有过AJAX跨域的问题的了,当时候知道了为什么会存在跨域,以及跨域解决的方案有哪些,今天随着课程的学习,又加深了AJAX跨域的理解,以此记录下来。为什么会发生产生跨域问题?上面的图也很清晰了...

weixin_35921127的博客 445

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

cordova ajax https,将手机升级到Android 9 Pie API 28修订版6后,Cordova App中出现Ajax错误...

我有一个使用Cordova 8.1.2开发的应用程序,并在Android 8.1 Oreo API Level 27 Revision 3下编译,可在P​​lay商店和注册用户中成功使用.在过去的几周中,一些用户已将手机升级到Android 9.0 Pie,当他们打开该应用并进行注册或登录操作时,他们会收到Ajax通信,并显示服务器错误.我已经在Android Studio的开发人员模式下以及在A...

weixin_34036667的博客 409

javascript语言精粹 微盘_JavaScript语言精粹(修订版)pdf

摘要“学习、理解、实践大师的思想,我们才有可能站在巨人的肩上,才有机会赶超大师,这本书就是开始。”“这是一本介绍JavaScript语言本质的重要书籍,值得任何正在或者想从事JavaScript开发的人阅读,并且非常需要反复阅读。”“如果说犀牛展现了 JavaScript 特性的丰富和功能的强大,蝴蝶(书)则完美诠释了 JavaScript 语言轻巧简洁的特点。”“它是一本很好的帮助你提高 Jav...

weixin_39957265的博客 658

试读《JavaScript语言精粹(修订版)》

这是小弟我首次参加有奖试读活动,也是我在Iteye上写的第一篇文章,有什么不妥的地方请各位批评指正。 初次接触JavaScript是网页上的那些“花里胡哨”的特技,当时很是好奇这些是怎么实现的。而现在经过了系统的学习之后才终于对这种强大的语言有所了解。 虽然在浏览器差异性以及安全性等方面的诟病使JavaScript没少被批评,但是金无足赤人无完人,没有一种绝对完美的语言...

weixin_34362991的博客 61

ajax servlet怎么接收_AJAX跨域完全讲解(修订版)

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3yAJAX跨域完全讲解我在收集AJAX面试题的时候其实就已经有过AJAX跨域的问题的了,当时候知道了为什么会存在跨域,以及跨域解决的方案有哪些,今天随着课程的学习,又加深了AJAX跨域的理解,以此记录下来。为什么会发生产生跨域问题?上面的图也很清晰了...

weixin_39712969的博客 248

谈下我对javascript的简单认识以及《JavaScript语言精粹(修订版)》 试读

    专门讲JavaScript的书 本人目前看过两本,一本是《JavaScript高级程序设计(实体书)》 ,一本是《高性能JavaScript(中英文对照电子版)》   第三本 我赶脚是 《JavaScript语言精粹(修订版)》 的实体书 , 或英文电子版(木有中奖的话)-------------作者序    1.javascript是什么  一种基于原...

将来的你一定会感谢现在拼命努力的你 230

Web Desktop App(修订版)

年前忽然想到一种桌面应用的模式——用Web方式实现。从表现方式上说,类似.net的XAML,但是基于现有技术实现,并且可以不受平台限制。比如可以用这样的方式实现一个资源管理器这样的东东。甚至可以按这种模式开发出一种类似于DesktopWebOS这样的东东,挂在不同的OS平台上。基本的结构是这样:用TurboGears(或者简单一点就直接用CherryPy)一类的技术实现一个WebSer

猛禽的编程艺术 5255
上一篇: (修订版)AJAX入门!
下一篇: Java 8的Stream代码,你能看懂吗?
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值