摘要:當(dāng)然了,和具體股票對象應(yīng)該是全局的變量這樣才能夠在別的方法中用到二驗(yàn)證碼校驗(yàn)對于驗(yàn)證碼檢查我們并不會陌生,我們在學(xué)習(xí)的時(shí)候已經(jīng)使用過了驗(yàn)證碼檢查了。
一、股票案例
我們要做的是股票的案例,它能夠無刷新地更新股票的數(shù)據(jù)。當(dāng)鼠標(biāo)移動到具體的股票中,它會顯示具體的信息。
我們首先來看一下要做出來的效果:
1.1服務(wù)器端分析首先,從效果圖我們可以看見很多股票基本信息:昨天收盤價(jià)、今天開盤價(jià)、最高價(jià)、最低價(jià)、當(dāng)前價(jià)格、漲幅。這些信息我們用一個(gè)類來描述出來。
我們發(fā)現(xiàn)數(shù)據(jù)是定時(shí)刷新的,于是我們需要一個(gè)定時(shí)器。
服務(wù)器端的數(shù)據(jù)和客戶端交互,我們使用JSON吧
1.2服務(wù)器端代碼 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
Stock的構(gòu)造函數(shù):
/** * id,name,yesterday這三個(gè)參數(shù)都是固定的,其他的屬性都是可變的。 * 因此我們構(gòu)造函數(shù)就傳入這三個(gè)值 * */ public Stock(String id, String name, double yesterday) { this.id = id; this.name = name; this.yesterday = yesterday; //把開盤價(jià)設(shè)定為-1,后面在定時(shí)器計(jì)算出來的隨機(jī)數(shù),如果發(fā)現(xiàn)開盤價(jià)是-1,就設(shè)置第一次的隨機(jī)數(shù)為開盤價(jià) this.today = -1; //把最高、最低、當(dāng)前的價(jià)格都暫且設(shè)置成昨天的開盤價(jià),后面我們可以變化的 this.highest = yesterday; this.current = yesterday; this.lowest = yesterday; }
setCurrent()方法代碼:
/** * 每次設(shè)置當(dāng)前價(jià)錢的時(shí)候,最高、最低、漲幅都應(yīng)該隨著當(dāng)前價(jià)錢而變化的 */ public void setCurrent(double current) { //計(jì)算出漲幅或跌幅 double range = (current - this.yesterday) / this.yesterday; //設(shè)置漲幅和跌幅不能超過10%,當(dāng)前的價(jià)格只能是昨天開盤價(jià)的1.1倍或0.9倍 //當(dāng)前價(jià)格應(yīng)該是兩位小數(shù) 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; //如果今天開盤價(jià)沒設(shè)定,那么就將第一次的當(dāng)前價(jià)作為今天的開盤價(jià) 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; } //格式化漲幅的字符串,整數(shù)兩位,小數(shù)兩位 DecimalFormat formatRange = new DecimalFormat("##.##%"); this.range = formatRange.format(range); }1.2.2Servlet的代碼
init()初始化代碼:
/** * 重寫init()方法,加入一些配置內(nèi)容 */ @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); //生成隨機(jī)數(shù) final Random random = new Random(); //格式化生成的隨機(jī)數(shù) 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%,我們用來做正負(fù) if (random.nextBoolean()) { baidu = 0 - baidu; } if (random.nextBoolean()) { ali = 0 - ali; } if (random.nextBoolean()) { tengxun = 0 - tengxun; } if (random.nextBoolean()) { geogle = 0 - geogle; } //設(shè)置它們的當(dāng)前價(jià)格 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); }
服務(wù)器一啟動就應(yīng)該初始化Servlet
Refresh Refresh 1 Refresh /Refresh
doPost()代碼:
//封裝成JSON格式,返回給瀏覽器 StringBuffer buffer = new StringBuffer(); //這里我們拼接成4個(gè)對象 buffer.append("({"); for (Map.Entryentry : 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(","); } //消除最后一個(gè)逗號 buffer.deleteCharAt(buffer.lastIndexOf(",")); //最后補(bǔ)上括號 buffer.append("})"); //返回給瀏覽器 response.getWriter().write(buffer.toString());
拼接成的JSON數(shù)據(jù):
({ 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客戶端分析之一
客戶端要做的就是顯示數(shù)據(jù),每隔兩秒就和服務(wù)器進(jìn)行一次交互
用到Ajax和setInterval()方法
1.3.1html代碼使用div嵌套span和a標(biāo)簽來進(jìn)行顯示,span裝載的就是服務(wù)端返回json的current數(shù)據(jù)
1.3.2javaScript代碼
解析JSON,并設(shè)置span的內(nèi)容
function show() { getStock(); //每兩秒就取一次數(shù)據(jù) setInterval(getStock, 2000); } var httpRequest; function getStock() { //力求是最新的響應(yīng)數(shù)據(jù),如果存在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) { //得到服務(wù)器端返回的JSON數(shù)據(jù) var text = httpRequest.responseText; //解析成JavaScript對象 var json = eval(text); //遍歷出每個(gè)JSON對象【也就是json的id】 for(var id in json) { //得到每個(gè)stock對象 var stock = json[id]; //將當(dāng)前的價(jià)格設(shè)置到span節(jié)點(diǎn)里面 document.getElementById(id).innerHTML = stock.current; //比較當(dāng)前價(jià)格和昨天開盤價(jià)格,如果大于就是紅色,小于就是綠色 if(stock.current>stock.yesterday) { document.getElementById(id).style.color = "red"; }else { document.getElementById(id).style.color = "green"; } } } } }
效果
1.4客戶端分析之二當(dāng)鼠標(biāo)移動到具體的股票超鏈接的時(shí)候,會顯示具體的數(shù)據(jù),并且數(shù)據(jù)是動態(tài)的
在超鏈接上綁定事件
取出和服務(wù)器交互的數(shù)據(jù),顯示在頁面上
1.4.1html代碼:綁定事件,只要鼠標(biāo)移動到超鏈接上就觸發(fā)事件
1.4.2css代碼昨收:今收:最低:當(dāng)前:最高:漲幅:
詳細(xì)框的信息默認(rèn)是隱藏的
1.4.3javaScript代碼得到交互的數(shù)據(jù),設(shè)置span里面的值
function update() { var stock = json[sid]; //得到相對應(yīng)的控件 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"); //設(shè)置具體信息的值 high.innerHTML = stock.high; range.innerHTML = stock.range; current.innerHTML = stock.current; yesterday.innerHTML = stock.yesterday; today.innerHTML = stock.today; low.innerHTML = stock.low; //如果數(shù)值比昨天開盤價(jià)低,反則就是紅色 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"; } //如果現(xiàn)在的價(jià)格比昨天開盤高,那么漲幅是紅色 if (stock.current > stock.yesterday) { range.style.color = "red"; current.style.color = "red"; } else { range.style.color = "green"; current.style.color = "green"; } }
只有鼠標(biāo)移到超鏈接上,才明確id的值是多少!
function callBackFunction() { if (httpRequest.readyState == 4) { if (httpRequest.status == 200) { //得到服務(wù)器端返回的JSON數(shù)據(jù) json= eval(httpRequest.responseText); //更新詳細(xì)框的數(shù)據(jù),當(dāng)鼠標(biāo)移動到超鏈接上才確定有id,于是判斷有沒有id if(sid) { update(); } //遍歷出每個(gè)JSON對象【也就是json的id】 for (var id in json) { //得到每個(gè)stock對象 var stock = json[id]; //將當(dāng)前的價(jià)格設(shè)置到span節(jié)點(diǎn)里面 document.getElementById(id).innerHTML = stock.current; //比較當(dāng)前價(jià)格和昨天開盤價(jià)格,如果大于就是紅色,小于就是綠色 if (stock.current > stock.yesterday) { document.getElementById(id).style.color = "red"; } else { document.getElementById(id).style.color = "green"; } } } } } function showTool(node) { //得到鼠標(biāo)移動到具體股票的id sid = node.parentNode.getElementsByTagName("span")[0].id; //把詳細(xì)框框顯示出來 document.getElementById("toolTip").style.display = "block"; } function clearTool() { document.getElementById("toolTip").style.display = "none"; }1.5最終效果: 1.6總結(jié)要點(diǎn)
①:這是由AJAX來實(shí)現(xiàn)的,因?yàn)樗鼰o刷新的動態(tài)交互數(shù)據(jù)。
②:服務(wù)器端應(yīng)該保存著股票的基本信息。于是乎,我們用一個(gè)類來裝載著這些信息【信息之間的關(guān)系就不一一說明了,因?yàn)槊總€(gè)案例用的可能都不一樣】
③:用到了DecimalFormat類來格式化小數(shù)變?yōu)樽约合胍母袷?/p>
④:使用HashMap來裝載這些股票,使用Map集合主要是在客戶端中,可以通過鍵來訪問具體的股票,只要能訪問到股票了,那么一切就好說了。
⑤:當(dāng)然啦,裝載股票的任務(wù)就交給init()方法,因?yàn)橹恍枰b載一次。
⑥:我們會發(fā)現(xiàn),股票的信息是不斷會變化的,所以我們使用定時(shí)器和Random類來不斷修改股票的信息
⑦:JavaScript和服務(wù)端交互使用AJAX,要么使用XML,要么就是JSON,這次我們采用的是JSON
⑧:JavaScript使用XMLHttpRequest對象得到Servlet返回給瀏覽器的JSON數(shù)據(jù),解析JSON數(shù)據(jù),變成是JavaScript對象
⑨:在頁面上顯示服務(wù)端帶過來的數(shù)據(jù),一般都是使用div來顯示【塊級】,用控件綁定id,在JavaScript中得到控件,填充數(shù)據(jù)。這樣就是動態(tài)地修改頁面的數(shù)據(jù)了。
⑩:瀏覽器想要不斷地從服務(wù)端獲取股票的數(shù)據(jù),那么就需要不斷地與服務(wù)端交互,解析JSON,填充數(shù)據(jù).....這種我們可以通過setInterval()定時(shí)器來做
①①:想要修改字體的顏色,只要獲取它的控件再style.color就可以修改了。
①②:鼠標(biāo)移動到具體的股票鏈接的時(shí)候,會出現(xiàn)股票的詳細(xì)信息時(shí),這明顯就是為超鏈接綁定了事件
①③:股票的詳細(xì)信息用一個(gè)框框裝載著,那么我們就在css中初始化這個(gè)框框,它平時(shí)是不顯示出來的,只用在鼠標(biāo)移到它那里的時(shí)候才顯示,我們把display=“none”就行了。
①④:在響應(yīng)事件的時(shí)候,我們需要知道用戶是移動到哪一個(gè)超鏈接上,所以要獲取得到具體的超鏈接id。知道id以后,我們就知道用戶想要知道的股票是哪一個(gè)了。
①⑤:股票的信息也想要及時(shí)的更新,那么我們想把它抽取成一個(gè)方法,在AJAX回調(diào)方法中加入進(jìn)去就行了。當(dāng)然了,id和具體股票對象應(yīng)該是全局的變量【這樣才能夠在別的方法中用到】
二、驗(yàn)證碼校驗(yàn)對于驗(yàn)證碼檢查我們并不會陌生,我們在學(xué)習(xí)Session的時(shí)候已經(jīng)使用過了驗(yàn)證碼檢查了。詳細(xì)可參考:http://blog.csdn.net/hon_3y/article/details/54799494#t11
我們當(dāng)時(shí)是同步檢查驗(yàn)證碼是否正確的,其實(shí)沒有必要。因?yàn)?strong>就驗(yàn)證一個(gè)輸入框的數(shù)據(jù),沒必要使用同步的方式驗(yàn)證【使用異步對用戶體驗(yàn)更加友好】
2.1分析當(dāng)用戶輸入完4位數(shù)字的時(shí)候,就去服務(wù)器端驗(yàn)證是否需要相同,如果相同,那么返回一個(gè)打鉤的圖片。如果不同,那么就返回一個(gè)打叉的圖片
2.1.1前臺分析綁定鍵盤輸入事件
當(dāng)輸入數(shù)達(dá)到4的時(shí)候,就與服務(wù)器交互
得到服務(wù)器帶過來的圖片,使用DOM添加到對應(yīng)的位置
2.1.2后臺分析得到前臺帶過來的值
判斷該值與Session保存的是否相同
根據(jù)判斷值返回對應(yīng)的圖片
2.2編寫JSP值得注意的是:要獲取td定義的id,外邊一定要套上table標(biāo)簽。。。我在剛開始寫的時(shí)候,是沒有table標(biāo)簽的。然后死活得不到td的標(biāo)簽....很煩...
<%-- 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" %>驗(yàn)證碼校驗(yàn) <%--###################展示頁面#############################--%>
驗(yàn)證碼: |
處理請求的Servlet
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 { //得到帶過來的數(shù)據(jù) String keyValue = request.getParameter("keyValue"); //得到Session中的數(shù)據(jù) String checkCodeInSession = (String) request.getSession().getAttribute("CHECKNUM"); response.setContentType("text/html;charset=UTF-8"); String src = "images/MsgError.gif"; //判斷倆數(shù)據(jù)是否相同 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測試 2.4總結(jié)
使用AJAX驗(yàn)證校驗(yàn)碼主要是監(jiān)聽鍵盤的響應(yīng)事件
要獲取td標(biāo)簽的數(shù)據(jù),外邊一定要套有table標(biāo)簽!【別偷懶不寫table標(biāo)簽】
當(dāng)輸入框的數(shù)值數(shù)為4的時(shí)候就與服務(wù)器進(jìn)行交互,服務(wù)器返回一張圖片。
可以用自定義的trim()把數(shù)據(jù)的前后空格去掉,通過正則表達(dá)式來去除空格。
當(dāng)輸入框的數(shù)值數(shù)不為4的時(shí)候就把圖片的內(nèi)容清空
如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號:Java3y
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76319.html
摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號:Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...
摘要:頁面向傳遞一個(gè)參數(shù),其值表示調(diào)用那個(gè)方法用戶名密碼驗(yàn)證碼換一張登錄重置代碼得到所有的錯(cuò)誤信息,循環(huán)遍歷之。 jsp頁面: My JSP login.jsp starting page body{ background-image:url(image/bg.jpg); background-repeat: repeat-x;...
摘要:頁面向傳遞一個(gè)參數(shù),其值表示調(diào)用那個(gè)方法用戶名密碼驗(yàn)證碼換一張登錄重置代碼得到所有的錯(cuò)誤信息,循環(huán)遍歷之。 jsp頁面: My JSP login.jsp starting page body{ background-image:url(image/bg.jpg); background-repeat: repeat-x;...
閱讀 3213·2021-11-22 15:25
閱讀 3928·2021-11-17 09:33
閱讀 3418·2021-11-08 13:15
閱讀 3100·2021-09-22 10:56
閱讀 612·2021-08-31 09:45
閱讀 2807·2019-08-30 13:49
閱讀 3119·2019-08-30 12:52
閱讀 1194·2019-08-29 17:05