AJAX应用【股票案例】

Wesley13
• 阅读 648

股票案例

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

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

AJAX应用【股票案例】

服务器端分析

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

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

服务器端的数据和客户端交互,我们使用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

    Refresh Refresh 1 Refresh /Refresh

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

  • 效果

AJAX应用【股票案例】


客户端分析之二

当鼠标移动到具体的股票超链接的时候,会显示具体的数据,并且数据是动态的
- 在超链接上绑定事件
- 取出和服务器交互的数据,显示在页面上

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应用【股票案例】

总结要点

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

点赞
收藏
评论区
推荐文章
Irene181 Irene181
3年前
用Python编程借助现有量化平台编写股票交易策略和回测分析
一、简介大家好,我是Snowball。今天给大家分享的内容是基于Python编程,实现股票交易相关功能开发,如果读者对股票或金融衍生物交易不太了解,又比较感兴趣的话可自行查询相关资料。接下来笔者会给大家介绍股票交易中的常见几种交易策略实现思路和源码编写过程,如果大家听说过量化交易这个词语的话,对其中的交易策略或许了解过,大概意思就是在股票、加密货币或者金融衍
Irene181 Irene181
3年前
项目实战——打造一款股票区间交易盯盘系统
一、简介大家好,我是Snowball。今天给大家分享的内容是基于Java编程,实现股票交易相关功能开发,如果读者对股票或金融衍生物交易不太了解,又比较感兴趣的话可自行查询相关资料。在这篇文章里边,介绍了两个策略,,这篇文章,我们来实战个大的项目。常见的交易策略有很多种,例如趋势型,网格型,剥头皮,概率法则,高频交易等,今天主要给大家介绍2种低频的交易
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Aidan075 Aidan075
3年前
厉害了,股票K线图还能这么画!
大家好,我是小五🐶发现大家还是最喜欢股票基金话题呀~那说到股票基金就不得不提——K线图!那小五今天就带大家👉用python来轻松绘制高颜值的K线图🚀获取股票交易数据巧妇难为无米之炊,做可视化也离不开数据。本文我将以酱香型科技——贵州茅台为例,获取它的近期股票数据并绘制K线图。如果我们要特意去动手去写爬虫,就显得有些多余了,这里
Wesley13 Wesley13
3年前
java通过sina端口提取股票历史数据并存入MySQL
 1.提取股票代码代码见:http://www.oschina.net/code/snippet\_2688840\_55337(http://www.oschina.net/code/snippet_2688840_55337) 2抓取sina股票的json页面数据;代码见:http://www.oschina.net/code/snip
伊丽莎白-简 伊丽莎白-简
3年前
简说设计模式——外观模式
一、什么是外观模式  有些人可能炒过股票,但其实大部分人都不太懂,这种没有足够了解证券知识的情况下做股票是很容易亏钱的,刚开始炒股肯定都会想,如果有个懂行的帮帮手就好,其实基金就是个好帮手,支付宝里就有许多的基金,它将投资者分散的资金集中起来,交由专业的经理人进行管理,投资于股票、债券、外汇等领域,而基金投资的收益归持有者所有,管理机
Stella981 Stella981
3年前
Amazon真有说的那么不好么?
坊间传说Amazon是血汗工厂加班、PIP、跳楼种种负面新闻缠身股票Vest方式也比较抠四年按照5%:15%:40%:40%很多亚麻呆过的人都表示亚麻其实没有那么不好PTO很多、股票升值空间大公司业务很锻炼人去了亚麻,等于有了一份背书跳槽哪里都不用愁亚麻是NewGrads友好公司
Stella981 Stella981
3年前
LightningChart.NET创建显示财务数据的2D StockSeries图表
本教程说明了如何从CSV文件加载财务数据并使用LightningChartStockSeries显示它们。股票系列用于以烛台和股票条格式可视化股票交易数据。本教程假定您已在WinForms或WPF应用程序上使用LightningChart创建了新图表。如果没有,请按照我们的简单2D图表创建应用程序。!(https://image.evget.com
Python进阶者 Python进阶者
1年前
推荐一个下载股票相关数据的库——tuhsare
大家好,我是皮皮。一、前言这个事情还得从前几天在Python白银群【厚德载物】问了一个Python股票网络爬虫的问题说起,因为这个股票数据抓取的问题,引发了大家激烈的探讨,以致于后来大佬们纷纷参与进来。图片二、实现过程这里【袁学东】分享了一个tushare
Python进阶者 Python进阶者
12个月前
Pandas实现这列股票代码中10-12之间的股票筛出来
大家好,我是皮皮。一、前言前几天在Python白银交流群【YVONNE🎉】问了一个Pandas数据分析的问题,一起来看看吧。问题描述:原始数据长这样,我需要把SHRCD这列股票代码中1012之间的股票筛出来。原始数据如下图所示:他的报错内容如下所示:他说