版本历史&代码示例之:WebSocket、JSTL

前言

你好,我是方同学(YourBatman)

十年的清流网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。网络营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整清流建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联公司从事“清流网站设计”,“清流网站推广”以来,每个客户项目都认真落实执行。

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

紧接着上一篇讲完Servlet、JSP、EL表达式后,本文尝试把WebSocket和JSTL再疏通疏通。

所属专栏

BATutopia-Java EE

相关下载

  • 工程源代码:https://github.com/yourbatman/BATutopia-java-ee
  • 【女娲Knife-Initializr工程】访问地址:http://152.136.106.14:8761
  • Java开发软件包(Mac):https://wangpan.yourbatman.cn/s/rEH0 提取码:javakit
  • 程序员专用网盘上线啦,开放注册送1G超小容量,帮你实践做减法:https://wangpan.yourbatman.cn

版本约定

Java EE:6、7、8

Jakarta EE:8、9、9.1

正文

WebSocket

WebSocket是一种在单个TCP连接上进行全双工通信的协议。随着HTML5的诞生,WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket协议本质上是一个基于TCP的协议,它由通信协议和编程API组成,WebSocket能够在浏览器和服务器之间建立双向连接,以基于事件的方式,赋予浏览器实时通信能力。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。工作流程如下图:

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

注意:WebSocket的Client可以是浏览器,也可是WebSocket的终端(如Java应用、Go应用)。

 
 
 
 
  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版本号 
  23.  
  24.  
  25.     org.apache.tomcat 
  26.     tomcat-websocket 
  27.     Tomcat版本号 
  28.  

版本历程

servlet-3.1版本开始支持。WebSocket 1.1 版与 1.0 版完全向后兼容,只在javax.websocket.Session中添加了两个方法:

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

生存现状

作为Http协议的“补充”,很好的弥补了其不足,在Web领域实时推送,也被称作Realtime技术。这种技术大大提升交互体验,拥有广泛的应用场景:在线聊天(如web版微信)、在线客服系统、评论系统等等。

总的来讲,WebSocket作为新贵,生存现状挺好,前景一片光明。

实现(框架)

WebSocket其实是构建在Http协议之上的,所以对于Java语言来讲它依旧由Web容器来提供实现。

概念区分:Web容器不一定是Servlet容器,而Servlet容器一定是Web容器

除此之外也有独立实现:

  • client端实现:org.eclipse.jetty.websocket:javax-websocket-client-impl
  • server端实现:org.eclipse.jetty.websocket:javax-websocket-server-impl对于Client来讲,一般都是浏览器。

代码示例

前面有提到,WebSocket的Client端既可以是浏览器(现代的浏览器100%都支持此协议,若需要考虑浏览器兼容问题(比如国外现在依旧有使用老版IE浏览器的),可以使用socketio框架哈),也可以是Java应用。本示例就加点“难度”,用Java应用作为WebSocket的客户端。当然喽,服务端肯定也是Java应用呀。

创建demo项目,结构如下:

其中client为jar,server为war。

书写Server端代码,提供一个服务端点:

 
 
 
 
  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.     // 当前连接上来的连接们(每一个连接都是一个WsServerDemo实例,包含一个Session会话) 
  13.     private static Set webSocketSet = new CopyOnWriteArraySet<>(); 
  14.     // 会话 
  15.     private Session session; 
  16.  
  17.     /** 
  18.      * 建连成功的回调 
  19.      */ 
  20.     @OnOpen 
  21.     public void onOpen(Session session) { 
  22.         this.session = session; 
  23.         webSocketSet.add(this); // 保存当前连接 
  24.         System.out.println("Server有新连接加入!当前在线人数为" + webSocketSet.size()); 
  25.     } 
  26.  
  27.     /** 
  28.      * 连接关闭调用的方法 
  29.      */ 
  30.     @OnClose 
  31.     public void onClose() { 
  32.         webSocketSet.remove(this); 
  33.         System.out.println("Server有一连接关闭!当前在线人数为" + webSocketSet.size()); 
  34.     } 
  35.  
  36.     /** 
  37.      * 收到客户端消息后调用的方法 
  38.      */ 
  39.     @OnMessage 
  40.     public void onMessage(String message) throws IOException { 
  41.         System.out.println("Server来自客户端的消息:" + message); 
  42.         sendMessage("会话[" + session.getId() + "]的消息已经收到,内容为:" + message); 
  43.         // // =======群发消息========= 
  44.         // for (WsServerDemo item : webSocketSet) { 
  45.         //     try { 
  46.         //         item.sendMessage(message); 
  47.         //     } catch (IOException e) { 
  48.         //         continue; 
  49.         //     } 
  50.         // } 
  51.     } 
  52.  
  53.     /** 
  54.      * 发生错误时调用 
  55.      */ 
  56.     @OnError 
  57.     public void onError(Throwable error) { 
  58.         System.out.println("Server发生错误:" + error.getMessage()); 
  59.     } 
  60.  
  61.     /** 
  62.      * 发送消息 
  63.      */ 
  64.     public void sendMessage(String message) throws IOException { 
  65.         this.session.getBasicRemote().sendText(message); 
  66.     } 
  67.  

我这里简便起见,使用web容器直接实现。有兴趣/想深究websocket的同学,可使用org.eclipse.jetty.websocket:javax-websocket-server-impl通过API方式去启动Server,本文只演示用该方式启动client哈,二者兼顾嘛。

使用编程方式书写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.     // 会话(与服务端建立的会话) 
  13.     private Session session; 
  14.  
  15.     /** 
  16.      * 建连成功的回调 
  17.      */ 
  18.     @OnOpen 
  19.     public void onOpen(Session session) throws IOException { 
  20.         this.session = session; 
  21.         System.out.println("Client连接到服务端成功,会话ID:" + session.getId()); 
  22.         sendMessage("这是一条来自Client端,会话["+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会话" + session.getId() + "已断开"); 
  33.     } 
  34.  
  35.     /** 
  36.      * 发送消息 
  37.      */ 
  38.     public void sendMessage(String message) throws IOException { 
  39.         this.session.getBasicRemote().sendText(message); 
  40.     } 

用main方法启动Client端,去连接Server端并发送消息:

 
 
 
 
  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.         // 顺序执行5次会话,端口后再建立新会话 
  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端控制台日志:

 
 
 
 
  1. Client连接到服务端成功,会话ID:1 
  2. Client端收到消息: 会话[0]的消息已经收到,内容为:这是一条来自Client端,会话[1]的消息 
  3. Client会话1已断开 
  4. Client连接到服务端成功,会话ID:2 
  5. Client端收到消息: 会话[1]的消息已经收到,内容为:这是一条来自Client端,会话[2]的消息 
  6. Client会话2已断开 
  7. Client连接到服务端成功,会话ID:3 
  8. Client端收到消息: 会话[2]的消息已经收到,内容为:这是一条来自Client端,会话[3]的消息 
  9. Client会话3已... 

server端控制台日志:

 
 
 
 
  1. Server有新连接加入!当前在线人数为1 
  2. Server来自客户端的消息:这是一条来自Client端,会话[1]的消息 
  3. Server有一连接关闭!当前在线人数为0 
  4. Server有新连接加入!当前在线人数为1 
  5. Server来自客户端的消息:这是一条来自Client端,会话[2]的消息 
  6. Server有一连接关闭!当前在线人数为0 
  7. Server有新连接加入!当前在线人数为1 
  8. Server来自客户端的消息:这是一条来自Client端,会话[3]的消息 
  9. Server有一连接关闭!当前在线人数为0 

说明:本文特意使用Java应用作为Client端是想让你更深刻的理解WebSocket的用法,实际场景中,其实大都是B/S模式,通过JavaScript作为客户端建立连接(相对简单)。

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

JSTL

Java server pages standarded tag library,即JSP标准标签库。主要提供给Java Web开发人员一个标准通用的标签库,开发人员可以利用这些标签取代 JSP页面上的Java代码,从而提高程序的可读性,降低程序的维护难度。

JSTL强依赖于JSP的存在而存在。

JSTL和EL表达式的目的是一样的:取代JSP页面上写Java代码。它比EL更为强大些,可以完成一些结构化逻辑任务,如:迭代、条件判断、XML文档操作、国际化、SQL等,下面简要介绍其主要标签。

  • 核心标签:也是著名C标签。在JSP文件开头引入c标签<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>,支持的常用函数有:
 
 
 
 
  1. 1. :用于在页面输出 
  2.  -  
  3. 2. :逻辑判断 
  4.  -    
  5.        body content   
  6.     
  7. 3. :逻辑判断。when和otherwise的父标签 
  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. :使用可选的查询参数创造一个URL地址 
  25. 7. :设置数据 
  26. 8. :删除数据 
  • 格式化标签:可对数字、日期时间等格式化。<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>,主要函数:
 
 
 
 
  1. 1. :格式化数字 
  2. 2. :解析字符串到数字、货币、百分比 
  3. 3. : 
  4. 4. : 
  • JSTL函数:一般用于辅助标签控制行为。<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>,主要函数:
 
 
 
 
  1. 1. fn:contains:判断字符串是否包含另外一个字符串  
  2.  -  
  3. 2. fn:indexOf:子字符串在母字符串中出现的位置  
  4.  - ${fn:indexOf(name, '-')} 
  5. 3. fn:toLowerCase:转为小写 
  6.  - ${fn.toLowerCase(product.name)} 
  • SQL标签,<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>。主要函数:
 
 
 
 
  1. 1.  

  • XML标签,<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>。主要函数:
 
 
 
 
  1. 1.  

除此之外,还提供了扩展点:自定义标签。

 
 
 
 
  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.  

说明:之前可能需要有jstl.jar和standard.jar两个Jar,但从1.2版本后这一个GAV即可。当然喽,99.99%情况下该jar无需你导入,由web容器负责

版本历程

JSTL也依赖于JSP而存在,所以和JSP版本有强关系。

JSTL 1.2版本可断定是最后一个版本,因为JSP已走到尽头,所以它也会随之消亡。

生存现状

同JSP。

实现(框架)

与Servlet相同的Web容器,由Web容器提供解析能力。如tomcat的标签库实现:http://tomcat.apache.org/taglibs

代码示例

实在没有应用场景了,略。

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

总结

WebSocket作为长连接的轻量级解决方案,会是B/S的新宠,一举替掉之前的长轮训等方案。滚滚长江东逝水,这或许就印证着技术在进步,时代在发展。

作为老一辈程序员的我,对EL表达式、JSTL这类技术依旧有记忆存留,但新时代的程序员可能没有必要再接触。本文就当做自留地,封存这段学习的记忆吧。

本文转载自微信公众号「BAT的乌托邦」

当前题目:版本历史&代码示例之:WebSocket、JSTL
链接地址:http://www.shufengxianlan.com/qtweb/news24/41974.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联