websockets_使用Java WebSockets,JSR 356和JSON映射到POJO的

websockets

因此,我一直在研究Tyrus (JSR 356 WebSocket for Java规范的参考实现)。 因为我一直在寻找测试工具,所以我对在Java中同时运行客户端和服务器端感兴趣。 因此,恐怕此博客文章中没有HTML5。

在此示例中,我们想来回发送JSON,并且因为我过时了,所以我希望能够绑定到POJO对象。 我将为此使用Jackson,因此我的Maven文件如下所示:

<dependencies><dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.0-rc3</version></dependency><dependency><groupId>org.glassfish.tyrus</groupId><artifactId>tyrus-client</artifactId><version>1.0-rc3</version></dependency><dependency><groupId>org.glassfish.tyrus</groupId><artifactId>tyrus-server</artifactId><version>1.0-rc3</version></dependency><dependency><groupId>org.glassfish.tyrus</groupId><artifactId>tyrus-container-grizzly</artifactId><version>1.0-rc3</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.2.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.2.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.2.0</version></dependency></dependencies>

因此,我们需要做的第一件事就是定义Encode / Decoder接口的实现来为我们完成这项工作。 这将做一些简单的反映来锻炼bean类是什么。 像使用JAX-WS一样,将它们放在同一个类中也更容易。 请注意,我们使用接口的流版本,并且仅处理文本内容。 (暂时忽略发送二进制数据的能力)

package websocket;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;
import java.io.Reader;
import java.io.Writer;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;public abstract class JSONCoder<T>implements Encoder.TextStream<T>, Decoder.TextStream<T>{private Class<T> _type;// When configured my read in that ObjectMapper is not thread safe//private ThreadLocal<ObjectMapper> _mapper = new ThreadLocal<ObjectMapper>() {@Overrideprotected ObjectMapper initialValue() {return new ObjectMapper();}};@Overridepublic void init(EndpointConfig endpointConfig) {ParameterizedType $thisClass = (ParameterizedType) this.getClass().getGenericSuperclass();Type $T = $thisClass.getActualTypeArguments()[0];if ($T instanceof Class) {_type = (Class<T>)$T;}else if ($T instanceof ParameterizedType) {_type = (Class<T>)((ParameterizedType)$T).getRawType();}}@Overridepublic void encode(T object, Writer writer) throws EncodeException, IOException {_mapper.get().writeValue(writer, object);}@Overridepublic T decode(Reader reader) throws DecodeException, IOException {return _mapper.get().readValue(reader, _type);}@Overridepublic void destroy() {}}

Bean类实际上非常简单,带有Coder的静态子类,以后我们可以使用它。

package websocket;public class EchoBean {public static class EchoBeanCode extendsJSONCoder<EchoBean> {}private String _message;private String _reply;public EchoBean() {}public EchoBean(String _message) {super();this._message = _message;}public void setMessage(String _message) {this._message = _message;}public String getMessage() {return _message;}public void setReply(String _reply) {this._reply = _reply;}public String getReply() {return _reply;}}

因此,我们需要实现服务器端点,因此可以采用两种方式之一,即注释POJO或扩展端点。 我要为服务器使用第一个,为客户端使用第二个。 实际上,此服务所做的全部工作就是将消息发布回客户端。 请注意编码和解码器的注册。 在这种情况下是相同的类。

package websocket;import java.io.IOException;import javax.websocket.EncodeException;
import javax.websocket.EndpointConfig;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import static java.lang.System.out;@ServerEndpoint(value="/echo",encoders = {EchoBean.EchoBeanCode.class},decoders = {EchoBean.EchoBeanCode.class})
public class EchoBeanService
{@OnMessagepublic void echo (EchoBean bean, Session peer) throws IOException, EncodeException {//bean.setReply("Server says " + bean.getMessage());out.println("Sending message to client");peer.getBasicRemote().sendObject(bean);}@OnOpenpublic void onOpen(final Session session, EndpointConfig endpointConfig) {out.println("Server connected "  + session + " " + endpointConfig);}
}

让我们看一下客户端bean,这次扩展了标准Endpoint类并为消息添加了特定的侦听器。 在这种情况下,当收到消息时,只需关闭连接即可简化我们的测试案例。 在现实世界中,管理这种连接显然会更加复杂。

package websocket;import java.io.IOException;import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.EncodeException;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;import static java.lang.System.out;@ClientEndpoint(encoders = {EchoBean.EchoBeanCode.class},decoders = {EchoBean.EchoBeanCode.class})
public class EchoBeanClient extends Endpoint
{public void onOpen(final Session session, EndpointConfig endpointConfig) {out.println("Client Connection open "  + session + " " + endpointConfig);// Add a listener to capture the returning event//session.addMessageHandler(new MessageHandler.Whole() {@Overridepublic void onMessage(EchoBean bean) {out.println("Message from server : " + bean.getReply());out.println("Closing connection");try {session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "All fine"));} catch (IOException e) {e.printStackTrace();}}});// Once we are connected we can now safely send out initial message to the server//out.println("Sending message to server");try {EchoBean bean = new EchoBean("Hello");session.getBasicRemote().sendObject(bean);} catch (IOException e) {e.printStackTrace();} catch (EncodeException e) {e.printStackTrace();}}
}

现在,使用Tyrus运行WebSocket独立非常简单,您只需实例化服务器并启动它。 请注意,这会启动守护程序线程,因此您需要确保它是否在main方法中,并且您需要执行一些操作来保持JVM的生命。

import org.glassfish.tyrus.server.Server;Server server = new Server("localhost", 8025, "/", EchoBeanService.class);
server.start();

因此客户相对简单; 但是在执行声明式方法时,我们需要在注册客户端类时显式注册编码器和解码器。

import javax.websocket.ClientEndpointConfig;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.Session;import org.glassfish.tyrus.client.ClientManager;// Right now we have to create a client, which will send a message then close
// when it has received a reply
//ClientManager client = ClientManager.createClient();
EchoBeanClient beanClient = new EchoBeanClient();Session session = client.connectToServer(beanClient, ClientEndpointConfig.Builder.create().encoders(Arrays.<Class<? extends Encoder>>asList(EchoBean.EchoBeanCode.class)).decoders(Arrays.<Class<? extends Decoder>>asList(EchoBean.EchoBeanCode.class)).build(),URI.create("ws://localhost:8025/echo"));// Wait until things are closed downwhile (session.isOpen()) {out.println("Waiting");TimeUnit.MILLISECONDS.sleep(10);
}

现在,其输出如下所示:

Server connected SessionImpl{uri=/echo, id='e7739cc8-1ce5-4c26-ad5f-88a24c688799', endpoint=EndpointWrapper{endpointClass=null, endpoint=org.glassfish.tyrus.core.AnnotatedEndpoint@1ce5bc9, uri='/echo', contextPath='/'}} javax.websocket.server.DefaultServerEndpointConfig@ec120d
Waiting
Client Connection open SessionImpl{uri=ws://localhost:8025/echo, id='7428be2b-6f8a-4c40-a0c4-b1c8b22e1338', endpoint=EndpointWrapper{endpointClass=null, endpoint=websocket.EchoBeanClient@404c85, uri='ws://localhost:8025/echo', contextPath='ws://localhost:8025/echo'}} javax.websocket.DefaultClientEndpointConfig@15fdf14
Sending message to server
Waiting
Waiting
Waiting
Waiting
Waiting
Waiting
Waiting
Waiting
Waiting
Waiting
Sending message to client
Message from server : Server says Hello
Closing connection
Waiting

有趣的是,这是第一次运行,会有一个暂停,我怀疑这是由于杰克逊(Jackson)自己设置的,但我没有时间进行分析。 我确实发现,这种漫长的延迟发生在第一篇文章上-尽管显然,这比一般地传递​​纯文本消息要慢。 差异是否对您很重要取决于您的应用程序。

将纯文本的性能与JSON流API(例如由新JSR提供的JSON流API)以及将这些值绑定到JSON POJO的版本进行比较将会很有趣。 也许是另一天的事情。

参考: Gerard Davison博客博客中的JCG合作伙伴 Gerard Davison 使用Java WebSockets,JSR 356和JSON映射到POJO 。

翻译自: https://www.javacodegeeks.com/2013/05/using-java-websockets-jsr-356-and-json-mapped-to-pojos.html

websockets

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349387.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查看mysql主从复制是否成功的命令_mysql主从复制 - hong查理的个人空间 - OSCHINA - 中文开源技术交流社区...

1.配置 my.cof服务器A(192.168.1.2)配置如下log-bin mysql-binserver-id 1expire-logs-days 7#日志设置最高7天replicate-do-db test #需要同步的binlog-ignore-db mysql #忽略同步的binlog-ignore-db information_schema #忽略同步的auto-increment-increment 2…

python抓取数据时失败_爬取数据缺失的补坑,Python数据爬取的坑坑洼洼如何铲平...

渣渣业余选手讲解&#xff0c;关于爬取数据缺失的补坑&#xff0c;一点点关于Python数据爬取的坑坑洼洼如何铲平&#xff0c;个人的一些心得体会&#xff0c;还有结合实例的数据缺失的补全&#xff0c;几点参考&#xff0c;仅供观赏&#xff0c;如有雷同&#xff0c;那肯定是我…

关于总决赛

可以将变量声明为final。 最终变量只能分配一次。 如果分配了最终变量&#xff0c;则将导致编译时错误&#xff0c;除非在分配前立即将其绝对取消分配。 分配任何最终变量后&#xff0c;将永远无法对其进行更改。 如果变量引用任何对象的任何实例&#xff0c;它将继续引用相同的…

java中void_关于java中void的用法?

阿波罗的战车void除了说明该方法没有返回值外&#xff0c;还有什么作用呢&#xff1f;构造方法同样也是没有返回值的&#xff0c;那它和void方法有什么区别呢&#xff1f;构造方法与方法又有什么区别&#xff1f;用具象的实物来表现的话三者有何种关系呢&#xff1f;id 除了说明…

卷积神经网络mnist手写数字识别代码_搭建经典LeNet5 CNN卷积神经网络对Mnist手写数字数据识别实例与注释讲解,准确率达到97%...

LeNet-5卷积神经网络是最经典的卷积网络之一&#xff0c;这篇文章就在LeNet-5的基础上加入了一些tensorflow的有趣函数&#xff0c;对LeNet-5做了改动&#xff0c;也是对一些tf函数的实例化笔记吧。环境 Pycharm2019Python3.7.6tensorflow 2.0 话不多说&#xff0c;先放完整源码…

glassfish_多种监视和管理GlassFish 3的方法

glassfishGlassFish 3支持多种监视和管理方法。 在本文中&#xff0c;我将简要介绍GlassFish提供的管理&#xff0c;监视和管理方法。 GlassFish管理控制台 GlassFish基于Web的管理控制台GUI可能是GlassFish管理最著名的界面。 默认情况下&#xff0c;运行GlassFish后&#xf…

java 阻塞锁_Java实现锁、公平锁、读写锁、信号量、阻塞队列、线程池等常用并发工具...

锁的实现锁的实现其实很简单&#xff0c;主要使用Java中synchronized关键字。public class Lock {private volatile boolean isLocked false;private Thread lockingThread null;public synchronized void lock() throws InterruptedExpection {while(isLocked){wait();}isLo…

flask-mail异步发送邮件_SpringBoot 2.0 集成 JavaMail ,实现异步发送邮件

一、JavaMail的核心API1、API功能图解2、API说明(1)、Message 类:javax.mail.Message 类是创建和解析邮件的一个抽象类子类javax.mail.internet.MimeMessage &#xff1a;表示一份电子邮件。 发送邮件时&#xff0c;首先创建出封装了邮件数据的 Message 对象&#xff0c; 然后把…

Java 9中什么是私有的?

在进行面试时&#xff0c;我发现大多数应聘者都不知道Java中的private修饰符真正意味着什么。 他们知道一些足以进行日常编码的事情&#xff0c;但还远远不够。 这不成问题。 足够了解就足够了。 但是&#xff0c;了解Java的一些内部工作仍然很有趣。 在极少数情况下&#xff0…

python国际象棋ai程序_用Python编写一个国际象棋AI程序

最近我用Python做了一个国际象棋程序并把代码发布在Github上了。这个代码不到1000行&#xff0c;大概20%用来实现AI。在这篇文章中我会介绍这个AI如何工作&#xff0c;每一个部分做什么&#xff0c;它为什么能那样工作起来。你可以直接通读本文&#xff0c;或者去下载代码&…

java switch case怎么判断范围_【转】Java期末复习攻略!

期末19年就这样要过去了&#xff0c;终于到了小时候作文里的未来呢&#xff01;然而&#xff0c;期末考试也随之来临了。不知大家“预习”的怎么样呢&#xff1f; 期末复习资料的放送快接近尾声了下面康康学长学姐们怎么教你们打java这个boss(下面是java大佬给大家的复习建议以…

java list 去重复元素_java List去掉重复元素的几种方式

使用LinkedHashSet删除arraylist中的重复数据(有序)List words Arrays.asList("a","b","b","c","c","d");HashSet setnew LinkedHashSet<>(words);for(String word:set){System.out.println(word);}使用Has…

spring aop示例_Spring JpaRepository示例(内存中)

spring aop示例这篇文章描述了一个使用内存中HSQL数据库的简单Spring JpaRepository示例。 该代码示例可从GitHub的Spring-JpaRepository目录中获得。 它基于带有注释的Spring-MVC-示例和此处提供的信息 。 JPA资料库 在此示例中&#xff0c;我们实现了一个虚拟bean&#xff1…

python人工智能入门优达视频_机器学习:优达教你搭建Python 环境的正确姿势

原标题&#xff1a;机器学习:优达教你搭建Python 环境的正确姿势为机器学习搭建好 Python 环境听起来简单&#xff0c;但有时候坑还不少。如果此前没有配置过类似的环境&#xff0c;很可能会苦苦折腾各种命令好几个小时。可是我明明只是想马上搞起来我的机器学习&#xff01; 在…

java web登录状态保持_java web用于保持状态的4种方法

方法一&#xff1a;网址重写通过在url地址后面添加若干的token作为查询字符串来实现。token的值一般为 键值url?key1value1&key2value2&...&keynvaluenurl与token之间需要用?分开&#xff0c;两个token之间则是需要用一个&符号隔开。此方法适用于token不需要…

python天天向上续2_2019/2/12 Python今日收获

Python day12——025&#xff0c;026字典&#xff1a;当索引不好用时 1.字典&#xff1a;python唯一的一个映射类型。用键值对存储数据&#xff0c;他的标志是大括号。一个键值组合叫一个项。键的类型既可以是字符串类型也可以是整形也可以是浮点型。 如&#xff1a;dict{1:one…

python生成矩阵_如何在Python中生成矩阵?

你的问题的答案取决于你的学习目标是什么。如果您试图让矩阵“点击”以便以后使用它们&#xff0c;我建议您查看一个Numpyarray&#xff0c;而不是一个列表列表。这将使您可以轻松地分割行、列和子集。只要试着从列表中获取一个列&#xff0c;你就会感到沮丧。 使用列表列表作为…

java ee cdi_Java EE CDI ConversationScoped示例

java ee cdi在本教程中&#xff0c;我们将向您展示如何在Web应用程序中创建和使用ConversationScoped Bean。 在CDI中&#xff0c;bean是定义应用程序状态和/或逻辑的上下文对象的源。 如果容器可以根据CDI规范中定义的生命周期上下文模型来管理其实例的生命周期&#xff0c;则…

js input 自动换行_深入Slate.js - 拯救 ContentEditble

我们是钉钉的文档协同团队&#xff0c;我们在做一些很有意义的事情&#xff0c;其中之一就是自研的文字编辑器。为了把自研文字编辑器做好&#xff0c;我们调研了开源社区各种优秀编辑器&#xff0c;Slate.js 是其中之一&#xff08;实际上&#xff0c;自研文字编辑器前&#x…

java main 如何不退出_为什么java main主线程退出了子线程还能运行;golang main结束所有协程都被结束了...

最近看golang main函数结束&#xff0c;所有协程都被结束了结论是这样&#xff1a;A不是main程的情况下&#xff0c;在A程里开启B程&#xff0c;A程执行完&#xff0c;A程return之后&#xff0c;B程不受影响&#xff0c;不会挂掉。所有子协程与main程同级的&#xff0c;与main程…