日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
版本歷史&代碼示例之:WebSocket、JSTL

前言

你好,我是方同學(xué)(YourBatman)

十年的清流網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整清流建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“清流網(wǎng)站設(shè)計(jì)”,“清流網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

若你還不太清楚Java EE是什么,可先移步這里:什么是Java EE?

緊接著上一篇講完Servlet、JSP、EL表達(dá)式后,本文嘗試把WebSocket和JSTL再疏通疏通。

所屬專欄

BATutopia-Java EE

相關(guān)下載

  • 工程源代碼:https://github.com/yourbatman/BATutopia-java-ee
  • 【女?huà)zKnife-Initializr工程】訪問(wèn)地址:http://152.136.106.14:8761
  • Java開(kāi)發(fā)軟件包(Mac):https://wangpan.yourbatman.cn/s/rEH0 提取碼:javakit
  • 程序員專用網(wǎng)盤上線啦,開(kāi)放注冊(cè)送1G超小容量,幫你實(shí)踐做減法:https://wangpan.yourbatman.cn

版本約定

Java EE:6、7、8

Jakarta EE:8、9、9.1

正文

WebSocket

WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議。隨著HTML5的誕生,WebSocket通信協(xié)議于2011年被IETF定為標(biāo)準(zhǔn)RFC 6455,并由RFC7936補(bǔ)充規(guī)范。WebSocket API也被W3C定為標(biāo)準(zhǔn)。

WebSocket協(xié)議本質(zhì)上是一個(gè)基于TCP的協(xié)議,它由通信協(xié)議和編程API組成,WebSocket能夠在瀏覽器和服務(wù)器之間建立雙向連接,以基于事件的方式,賦予瀏覽器實(shí)時(shí)通信能力。

WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡(jiǎn)單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)。在WebSocket API中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。工作流程如下圖:

Java API for WebSocket是Java的Web套接字,在2013年6月份伴隨著Java EE 7推出(1.0版本),Java EE 8升級(jí)到1.1版本。

注意:WebSocket的Client可以是瀏覽器,也可是WebSocket的終端(如Java應(yīng)用、Go應(yīng)用)。

 
 
 
 
  1.  
  2.  
  3.     javax.websocket 
  4.     javax.websocket-api 
  5.     1.1 
  6.     provided 
  7.  
  8.  
  9.  
  10.  
  11.     jakarta.websocket 
  12.     jakarta.websocket-api 
  13.     2.0.0 
  14.      
  15.     provided 
  16.  
  17.  
  18. 除此之外,一般情況下我們直接使用Web容器提供的Jar即可,如Tomcat 
  19.  
  20.     org.apache.tomcat.embed 
  21.     tomcat-embed-websocket 
  22.     Tomcat版本號(hào) 
  23.  
  24.  
  25.     org.apache.tomcat 
  26.     tomcat-websocket 
  27.     Tomcat版本號(hào) 
  28.  

版本歷程

servlet-3.1版本開(kāi)始支持。WebSocket 1.1 版與 1.0 版完全向后兼容,只在javax.websocket.Session中添加了兩個(gè)方法:

 
 
 
 
  1.  void addMessageHandler(Class clazz, MessageHandler.Partial handler) throws IllegalStateException; 
  2.  void addMessageHandler(Class clazz, MessageHandler.Whole handler) throws IllegalStateException; 

生存現(xiàn)狀

作為Http協(xié)議的“補(bǔ)充”,很好的彌補(bǔ)了其不足,在Web領(lǐng)域?qū)崟r(shí)推送,也被稱作Realtime技術(shù)。這種技術(shù)大大提升交互體驗(yàn),擁有廣泛的應(yīng)用場(chǎng)景:在線聊天(如web版微信)、在線客服系統(tǒng)、評(píng)論系統(tǒng)等等。

總的來(lái)講,WebSocket作為新貴,生存現(xiàn)狀挺好,前景一片光明。

實(shí)現(xiàn)(框架)

WebSocket其實(shí)是構(gòu)建在Http協(xié)議之上的,所以對(duì)于Java語(yǔ)言來(lái)講它依舊由Web容器來(lái)提供實(shí)現(xiàn)。

概念區(qū)分:Web容器不一定是Servlet容器,而Servlet容器一定是Web容器

除此之外也有獨(dú)立實(shí)現(xiàn):

  • client端實(shí)現(xiàn):org.eclipse.jetty.websocket:javax-websocket-client-impl
  • server端實(shí)現(xiàn):org.eclipse.jetty.websocket:javax-websocket-server-impl對(duì)于Client來(lái)講,一般都是瀏覽器。

代碼示例

前面有提到,WebSocket的Client端既可以是瀏覽器(現(xiàn)代的瀏覽器100%都支持此協(xié)議,若需要考慮瀏覽器兼容問(wèn)題(比如國(guó)外現(xiàn)在依舊有使用老版IE瀏覽器的),可以使用socketio框架哈),也可以是Java應(yīng)用。本示例就加點(diǎn)“難度”,用Java應(yīng)用作為WebSocket的客戶端。當(dāng)然嘍,服務(wù)端肯定也是Java應(yīng)用呀。

創(chuàng)建demo項(xiàng)目,結(jié)構(gòu)如下:

其中client為jar,server為war。

書(shū)寫Server端代碼,提供一個(gè)服務(wù)端點(diǎn):

 
 
 
 
  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. Send email to me 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/9/12 15:29 
  7.  * @since 0.0.1 
  8.  */ 
  9. @ServerEndpoint("/websocket/chat") 
  10. public class WsServer { 
  11.  
  12.     // 當(dāng)前連接上來(lái)的連接們(每一個(gè)連接都是一個(gè)WsServerDemo實(shí)例,包含一個(gè)Session會(huì)話) 
  13.     private static Set webSocketSet = new CopyOnWriteArraySet<>(); 
  14.     // 會(huì)話 
  15.     private Session session; 
  16.  
  17.     /** 
  18.      * 建連成功的回調(diào) 
  19.      */ 
  20.     @OnOpen 
  21.     public void onOpen(Session session) { 
  22.         this.session = session; 
  23.         webSocketSet.add(this); // 保存當(dāng)前連接 
  24.         System.out.println("Server有新連接加入!當(dāng)前在線人數(shù)為" + webSocketSet.size()); 
  25.     } 
  26.  
  27.     /** 
  28.      * 連接關(guān)閉調(diào)用的方法 
  29.      */ 
  30.     @OnClose 
  31.     public void onClose() { 
  32.         webSocketSet.remove(this); 
  33.         System.out.println("Server有一連接關(guān)閉!當(dāng)前在線人數(shù)為" + webSocketSet.size()); 
  34.     } 
  35.  
  36.     /** 
  37.      * 收到客戶端消息后調(diào)用的方法 
  38.      */ 
  39.     @OnMessage 
  40.     public void onMessage(String message) throws IOException { 
  41.         System.out.println("Server來(lái)自客戶端的消息:" + message); 
  42.         sendMessage("會(huì)話[" + session.getId() + "]的消息已經(jīng)收到,內(nèi)容為:" + message); 
  43.         // // =======群發(fā)消息========= 
  44.         // for (WsServerDemo item : webSocketSet) { 
  45.         //     try { 
  46.         //         item.sendMessage(message); 
  47.         //     } catch (IOException e) { 
  48.         //         continue; 
  49.         //     } 
  50.         // } 
  51.     } 
  52.  
  53.     /** 
  54.      * 發(fā)生錯(cuò)誤時(shí)調(diào)用 
  55.      */ 
  56.     @OnError 
  57.     public void onError(Throwable error) { 
  58.         System.out.println("Server發(fā)生錯(cuò)誤:" + error.getMessage()); 
  59.     } 
  60.  
  61.     /** 
  62.      * 發(fā)送消息 
  63.      */ 
  64.     public void sendMessage(String message) throws IOException { 
  65.         this.session.getBasicRemote().sendText(message); 
  66.     } 
  67.  

我這里簡(jiǎn)便起見(jiàn),使用web容器直接實(shí)現(xiàn)。有興趣/想深究websocket的同學(xué),可使用org.eclipse.jetty.websocket:javax-websocket-server-impl通過(guò)API方式去啟動(dòng)Server,本文只演示用該方式啟動(dòng)client哈,二者兼顧嘛。

使用編程方式書(shū)寫client端代碼:

 
 
 
 
  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. Send email to me 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/9/12 15:31 
  7.  * @since 0.0.1 
  8.  */ 
  9. @ClientEndpoint 
  10. public class WsClient { 
  11.  
  12.     // 會(huì)話(與服務(wù)端建立的會(huì)話) 
  13.     private Session session; 
  14.  
  15.     /** 
  16.      * 建連成功的回調(diào) 
  17.      */ 
  18.     @OnOpen 
  19.     public void onOpen(Session session) throws IOException { 
  20.         this.session = session; 
  21.         System.out.println("Client連接到服務(wù)端成功,會(huì)話ID:" + session.getId()); 
  22.         sendMessage("這是一條來(lái)自Client端,會(huì)話["+session.getId()+"]的消息"); 
  23.     } 
  24.  
  25.     @OnMessage 
  26.     public void onMessage(String message) { 
  27.         System.out.println("Client端收到消息: " + message); 
  28.     } 
  29.  
  30.     @OnClose 
  31.     public void onClose() { 
  32.         System.out.println("Client會(huì)話" + session.getId() + "已斷開(kāi)"); 
  33.     } 
  34.  
  35.     /** 
  36.      * 發(fā)送消息 
  37.      */ 
  38.     public void sendMessage(String message) throws IOException { 
  39.         this.session.getBasicRemote().sendText(message); 
  40.     } 

用main方法啟動(dòng)Client端,去連接Server端并發(fā)送消息:

 
 
 
 
  1. public class ClientApp { 
  2.  
  3.     private static URI uri = URI.create("ws://localhost:8080/websocket/chat"); 
  4.     private static Session session; 
  5.  
  6.     public static void main(String[] args) throws DeploymentException, IOException, InterruptedException { 
  7.         WebSocketContainer container = ContainerProvider.getWebSocketContainer(); 
  8.  
  9.         // 順序執(zhí)行5次會(huì)話,端口后再建立新會(huì)話 
  10.         for (int i = 0; i < 5; i++) { 
  11.             session = container.connectToServer(WsClient.class, uri); 
  12.             session.close(); 
  13.             TimeUnit.SECONDS.sleep(2); 
  14.         } 
  15.     } 

client端控制臺(tái)日志:

 
 
 
 
  1. Client連接到服務(wù)端成功,會(huì)話ID:1 
  2. Client端收到消息: 會(huì)話[0]的消息已經(jīng)收到,內(nèi)容為:這是一條來(lái)自Client端,會(huì)話[1]的消息 
  3. Client會(huì)話1已斷開(kāi) 
  4. Client連接到服務(wù)端成功,會(huì)話ID:2 
  5. Client端收到消息: 會(huì)話[1]的消息已經(jīng)收到,內(nèi)容為:這是一條來(lái)自Client端,會(huì)話[2]的消息 
  6. Client會(huì)話2已斷開(kāi) 
  7. Client連接到服務(wù)端成功,會(huì)話ID:3 
  8. Client端收到消息: 會(huì)話[2]的消息已經(jīng)收到,內(nèi)容為:這是一條來(lái)自Client端,會(huì)話[3]的消息 
  9. Client會(huì)話3已... 

server端控制臺(tái)日志:

 
 
 
 
  1. Server有新連接加入!當(dāng)前在線人數(shù)為1 
  2. Server來(lái)自客戶端的消息:這是一條來(lái)自Client端,會(huì)話[1]的消息 
  3. Server有一連接關(guān)閉!當(dāng)前在線人數(shù)為0 
  4. Server有新連接加入!當(dāng)前在線人數(shù)為1 
  5. Server來(lái)自客戶端的消息:這是一條來(lái)自Client端,會(huì)話[2]的消息 
  6. Server有一連接關(guān)閉!當(dāng)前在線人數(shù)為0 
  7. Server有新連接加入!當(dāng)前在線人數(shù)為1 
  8. Server來(lái)自客戶端的消息:這是一條來(lái)自Client端,會(huì)話[3]的消息 
  9. Server有一連接關(guān)閉!當(dāng)前在線人數(shù)為0 

說(shuō)明:本文特意使用Java應(yīng)用作為Client端是想讓你更深刻的理解WebSocket的用法,實(shí)際場(chǎng)景中,其實(shí)大都是B/S模式,通過(guò)JavaScript作為客戶端建立連接(相對(duì)簡(jiǎn)單)。

工程源代碼:https://github.com/yourbatman/BATutopia-java-ee

JSTL

Java server pages standarded tag library,即JSP標(biāo)準(zhǔn)標(biāo)簽庫(kù)。主要提供給Java Web開(kāi)發(fā)人員一個(gè)標(biāo)準(zhǔn)通用的標(biāo)簽庫(kù),開(kāi)發(fā)人員可以利用這些標(biāo)簽取代 JSP頁(yè)面上的Java代碼,從而提高程序的可讀性,降低程序的維護(hù)難度。

JSTL強(qiáng)依賴于JSP的存在而存在。

JSTL和EL表達(dá)式的目的是一樣的:取代JSP頁(yè)面上寫Java代碼。它比EL更為強(qiáng)大些,可以完成一些結(jié)構(gòu)化邏輯任務(wù),如:迭代、條件判斷、XML文檔操作、國(guó)際化、SQL等,下面簡(jiǎn)要介紹其主要標(biāo)簽。

  • 核心標(biāo)簽:也是著名C標(biāo)簽。在JSP文件開(kāi)頭引入c標(biāo)簽<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>,支持的常用函數(shù)有:
 
 
 
 
  1. 1. :用于在頁(yè)面輸出 
  2.  -  
  3. 2. :邏輯判斷 
  4.  -    
  5.        body content   
  6.     
  7. 3. :邏輯判斷。when和otherwise的父標(biāo)簽 
  8. 4. : : 
  9.  -    
  10.         
  11.          body content   
  12.         
  13.   ... 
  14.         
  15.       body content   
  16.      
  17.     
  18.   
  19. 5. : 
  20.  -    
  21.        body content   
  22.     
  23.  
  24. 6. :使用可選的查詢參數(shù)創(chuàng)造一個(gè)URL地址 
  25. 7. :設(shè)置數(shù)據(jù) 
  26. 8. :刪除數(shù)據(jù) 
  • 格式化標(biāo)簽:可對(duì)數(shù)字、日期時(shí)間等格式化。<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>,主要函數(shù):
 
 
 
 
  1. 1. :格式化數(shù)字 
  2. 2. :解析字符串到數(shù)字、貨幣、百分比 
  3. 3. : 
  4. 4. : 
  • JSTL函數(shù):一般用于輔助標(biāo)簽控制行為。<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>,主要函數(shù):
 
 
 
 
  1. 1. fn:contains:判斷字符串是否包含另外一個(gè)字符串  
  2.  -  
  3. 2. fn:indexOf:子字符串在母字符串中出現(xiàn)的位置  
  4.  - ${fn:indexOf(name, '-')} 
  5. 3. fn:toLowerCase:轉(zhuǎn)為小寫 
  6.  - ${fn.toLowerCase(product.name)} 
  • SQL標(biāo)簽,<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>。主要函數(shù):
 
 
 
 
  1. 1. 、、 

  • XML標(biāo)簽,<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>。主要函數(shù):
 
 
 
 
  1. 1. 、 

除此之外,還提供了擴(kuò)展點(diǎn):自定義標(biāo)簽。

 
 
 
 
  1.  
  2.  
  3.     javax.servlet.jsp.jstl 
  4.     jstl-api 
  5.     1.2 
  6.  
  7.  
  8.  
  9.  
  10.     jakarta.servlet.jsp.jstl 
  11.     jakarta.servlet.jsp.jstl-api 
  12.     2.0.0 
  13.      
  14.  

說(shuō)明:之前可能需要有jstl.jar和standard.jar兩個(gè)Jar,但從1.2版本后這一個(gè)GAV即可。當(dāng)然嘍,99.99%情況下該jar無(wú)需你導(dǎo)入,由web容器負(fù)責(zé)

版本歷程

JSTL也依賴于JSP而存在,所以和JSP版本有強(qiáng)關(guān)系。

JSTL 1.2版本可斷定是最后一個(gè)版本,因?yàn)镴SP已走到盡頭,所以它也會(huì)隨之消亡。

生存現(xiàn)狀

同JSP。

實(shí)現(xiàn)(框架)

與Servlet相同的Web容器,由Web容器提供解析能力。如tomcat的標(biāo)簽庫(kù)實(shí)現(xiàn):http://tomcat.apache.org/taglibs

代碼示例

實(shí)在沒(méi)有應(yīng)用場(chǎng)景了,略。

工程源代碼:https://github.com/yourbatman/BATutopia-java-ee

總結(jié)

WebSocket作為長(zhǎng)連接的輕量級(jí)解決方案,會(huì)是B/S的新寵,一舉替掉之前的長(zhǎng)輪訓(xùn)等方案。滾滾長(zhǎng)江東逝水,這或許就印證著技術(shù)在進(jìn)步,時(shí)代在發(fā)展。

作為老一輩程序員的我,對(duì)EL表達(dá)式、JSTL這類技術(shù)依舊有記憶存留,但新時(shí)代的程序員可能沒(méi)有必要再接觸。本文就當(dāng)做自留地,封存這段學(xué)習(xí)的記憶吧。

本文轉(zhuǎn)載自微信公眾號(hào)「BAT的烏托邦」


網(wǎng)頁(yè)標(biāo)題:版本歷史&代碼示例之:WebSocket、JSTL
本文URL:http://m.5511xx.com/article/cdheosc.html