股票案例

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

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

服务器端分析

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

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

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

服务器端代码

Stock股票类的代码

  • 股票基本信息:

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
  • Stock的构造函数:
    /**
* 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; }
  • setCurrent()方法代码:


    /**
* 每次设置当前价钱的时候,最高、最低、涨幅都应该随着当前价钱而变化的
*/
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);
}

Servlet的代码

  • init()初始化代码:

/**
* 重写init()方法,加入一些配置内容
*/
@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>
<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>
  • doPost()代码:


        //封装成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());
  • 拼接成的JSON数据:
({
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%'}
})

客户端分析之一

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

- 用到Ajax和setInterval()方法

html代码

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

javaScript代码

  • 解析JSON,并设置span的内容


        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'; }
} }
}
}
  • 效果


客户端分析之二

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

- 在超链接上绑定事件

- 取出和服务器交互的数据,显示在页面上

html代码:

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


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

css代码

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

    <style type="text/css">

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

javaScript代码

得到交互的数据,设置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';
}
}

只有鼠标移到超链接上,才明确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';
}

最终效果:

总结要点

①:这是由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和具体股票对象应该是全局的变量【这样才能够在别的方法中用到】

AJAX应用【股票案例】的更多相关文章

  1. AJAX应用【股票案例、验证码校验】

    一.股票案例 我们要做的是股票的案例,它能够无刷新地更新股票的数据.当鼠标移动到具体的股票中,它会显示具体的信息. 我们首先来看一下要做出来的效果: 1.1服务器端分析 首先,从效果图我们可以看见很多 ...

  2. 以股票案例入门基于SVM的机器学习

    SVM是Support Vector Machine的缩写,中文叫支持向量机,通过它可以对样本数据进行分类.以股票为例,SVM能根据若干特征样本数据,把待预测的目标结果划分成“涨”和”跌”两种,从而实 ...

  3. 在我的新书里,尝试着用股票案例讲述Python爬虫大数据可视化等知识

    我的新书,<基于股票大数据分析的Python入门实战>,预计将于2019年底在清华出版社出版. 如果大家对大数据分析有兴趣,又想学习Python,这本书是一本不错的选择.从知识体系上来看, ...

  4. AJAX应用小案例

    此案例在XAMPP本地服务器上运行,需要应用jquery3.1.1的版本,应用JSON传递数据 代码如下: html代码: <!DOCTYPE html><html lang=&qu ...

  5. 在Python里,用股票案例讲描述性统计分析方法(内容来自我的书)

    描述性统计是数学统计分析里的一种方法,通过这种统计方法,能分析出数据整体状况以及数据间的关联.在这部分里,将用股票数据为样本,以matplotlib类为可视化工具,讲述描述性统计里常用指标的计算方法和 ...

  6. ajax调用数据案例,二级联动

    题目:请针对移动端web浏览器制作一个结账数据信息展示页面 要求: 1. 页面样式除不使用表格呈现外,可自由选择其他呈现方式 2. 需符合移动端操作习惯 3. 可根据服务区.门店查询结账信息 4. 可 ...

  7. ajax基本原理与案例

    一.什么是Ajax AJAX即“Asynchronous Javascript And XML”( 异步 JavaScript和XML),AJAX不是一种新的编程语言,而是一种用于创建更好更快以及交互 ...

  8. jquery ajax/post 请求 案例

    @RequestMapping("/hello")    @ResponseBody    public Hello getJson(HttpServletRequest requ ...

  9. ajax总结及案例

    一.实验简介 目的:检验输入登录名在数据库中是否存在,如果存在,当鼠标移出登录名框后,会提示用户名已存在,并且鼠标指针自动回到登录名框内. 操作步骤: 1.获取登录名的值 2.根据获取的登录名,组织查 ...

随机推荐

  1. tomcat 组件研究一--启动过程总结

    作为java 开发者,从开始学习java 便知道tomcat 这个容器了,但是一直却没有怎么研究过它的内部结构,以前对tomcat的认识也仅仅局限在那几个常用的目录放什么东西,那几个常用的配置文件应该 ...

  2. Centos7安装mysql-5.7.19

    Centos7安装Mysql 一 mysql下载 地址: https://dev.mysql.com/downloads/mysql/#downloads 二 在centos7上创建安装文件存放.解压 ...

  3. 给出打印结果-setTimeout

    问题: 请给出打印结果: for(var i=0;i<5;i++){ setTimeout(function(){ console.log(i); },0); } 解析: 考的是setTimeo ...

  4. python--注释

    python中单行注释用#,多行注释用""",看下面的代码: #!/usr/bin/python #coding:utf-8 #编码方式 #打印一行* print &qu ...

  5. Python 使用期物处理并发

    抨击线程的往往是系统程序员,他们考虑的使用场景对一般的应用程序员来说,也许一生都不会遇到--应用程序员遇到的使用场景,99% 的情况下只需知道如何派生一堆独立的线程,然后用队列收集结果. 示例:网络下 ...

  6. WeQuant交易策略—Dual Thrust

    Dual Thrust策略 策略介绍 Dual Thrust是一个趋势跟踪系统,由Michael Chalek在20世纪80年代开发,曾被Future Thruth杂志评为最赚钱的策略之一. Dual ...

  7. WeQuant交易策略—RSI

    RSI指标策略 策略介绍 RSI(相对强弱指标),是通过一段时期内的平均收盘上涨和下跌数,计算价格上涨所产生的波动占整个波动的百分比,来分析市场买卖盘的意向和实力. 计算公式(以日为单位举例) RSI ...

  8. Windows权限提升基础知识和命令

    介绍 这篇文章是介绍window的权限提升,虽然不是一个全面的指南,但会试图覆盖主要的技术,常用的资源列表在文章底部,可供大家参考. window权限提升基础知识 初始信息收集 在开始提权之前,我们需 ...

  9. linux shell 之在线文本编辑sed

    sed命令 文件编辑 sed是一种文本编辑命令,通过终端读取文件数据到缓冲区,然后通过sed编辑文本,在输出到指定的文件,sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用 ...

  10. 接口测试 mock server 工具moco学习笔记

    看过乙醇分享的接口测试,自己练习了moco,这里呢,吧一些练习的笔记坐下记录,方便自己查阅. 开源地址https://github.com/dreamhead/moco  ,  到QuickStart ...