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

因此,我一直在研究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

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

将纯文本的性能与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

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

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

相关文章

CSS3效果:波浪效果

实现效果 如图所示&#xff1a; 首先得准备三张图&#xff0c;一张是浅黄色的背景图loading_bg.png&#xff0c;一张是深红色的图loading.png&#xff0c;最后一张为bolang.png。 css代码 body{background:#ffe894;}.loading_bg{width:113px; height:111px;background:url(lo…

集合、深浅拷贝、文件操作(读、写、追加)函数初识(参数)

小数据池#int比较数值is 比较内存地址id 测试内存地址#str不能含有特俗字符单个元素*数字&#xff0c;不能超过21i1 ‘a’*20i ‘a’*20id一样i1 ‘a’*21i ‘a’*21id不一样编码ascii 英文的数字&#xff0c;字母&#xff0c;特殊字符字节8位表示一个字节字符内容的最小…

html创建文件域的代码,word如何插入域代码

在word里怎么进行域代码的设置&#xff1f;如果知道要插入的域的域代码&#xff0c;可以将其直接键入在文档中。首先按 CtrlF9&#xff0c;然后在括号中键入代码就可以了。【Word插入域方法】1、Word2007中&#xff0c;在要插入域的位置单击。2、在“插入”选项卡上的“文字”组…

大学屌丝男

哈哈&#xff0c;来晚了呀转载于:https://www.cnblogs.com/wainiwann/p/7909765.html

前端页面适配的rem换算

为什么要使用rem 之前有些适配做法&#xff0c;是通过js动态计算viewport的缩放值&#xff08;initial-scale&#xff09;。 例如以屏幕320像素为基准&#xff0c;设置1&#xff0c;那屏幕375像素就是375/3201.18以此类推。 但直接这样强制页面缩放过于粗暴&#xff0c;会导致页…

lt form gt 在html,HTML lt;formgt; 标签的 accept

HTML <form> 标签的 accept2018-11-20在跨业务、跨网站发送数据或者业务升级的时候&#xff0c;我们有的时候需要指定发送数据的编码方式&#xff0c;比如页面表单的编码是UTF-8的&#xff0c;而提交到目标页面的编码是GBK编码时&#xff0c;会用到表单的accept-charset属…

使用Java ThreadLocals的意外递归保护

对于那些使用第三方工具来尝试扩展它们而又不完全了解它们的人来说&#xff0c;这是一个小技巧。 假定以下情况&#xff1a; 您想扩展一个公开分层数据模型的库&#xff08;假设您要扩展Apache Jackrabbit &#xff09; 该库在访问内容存储库的任何节点之前会内部检查访问权限…

今日头条竞价接口转发

一、代码 ①类名 public class TouTiao{public class model{public string site_id { get; set; }public string ad_id { get; set; }public List<Data> data { get; set; }}public class Data{public string label { get; set; }public string lable { get; set; }publi…

art-template辅助函数和子模板

art-template 前端使用 用途&#xff1a;主要用来处理数据和优化性能&#xff0c;与其他的一些模块化处理数据的插件相比&#xff0c;art-template处理性能好 不废话&#xff0c;上代码 1.art-template基本语法使用 <script src"template.js"></script&…

微处理器 微型计算机系统,作业答案11微处理器微型计算机和微型计算机系统三者之间.DOC...

作业答案11微处理器微型计算机和微型计算机系统三者之间第1章 作 业 答案1.1 微处理器、微型计算机和微型计算机系统三者之间有什么不同?把CPU(运算器和控制器)用大规模集成电路技术做在一个芯片上,即为微处理器。微处理器加上一定数量的存储器和外部设备(或外部设备的接口)构…

C# 对轻量级(IoC Container)依赖注入Unity的使用

概述 Unity是一个轻量级的可扩展的依赖注入容器&#xff0c;支持构造函数&#xff0c;属性和方法调用注入。Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问题。构建一个成功应用程序的关键是实现非常松散的耦合设计。松散耦合的应用程序更灵活&#xff0c;更易于…

为什么同步的StringBuffer从来都不是一个好主意

介绍 StringBuffer是用于可变字符串的同步类。 使其同步的主要问题是 它通常用作局部变量&#xff0c;因此使其同步只会使其变慢。 以多线程方式使用它从来不是一个好主意。 这个问题是开发人员认为使用StringBuffer的方法在不使用时本身就是线程安全的。 StringBuffer的问题…

大工20秋计算机组成原理在线作业2,大工14秋《计算机组成原理》在线作业2答案...

大工14秋《计算机组成原理》在线作业2单选题 判断题一、单选题(共 10 道试题&#xff0c;共 50 分。)1. 存储周期是指( )。A. 存储器的读出时间B. 存储器的写入时间C. 存储器进行连续读或写操作所允许的最短时间间隔D. 存储器进行连续读或写操作所允许的最长时间间隔正确答案&a…

css清除浮动

css设计浮动属性的主要目的&#xff0c;是为了实现文本绕排图片的效果。 一.浮动 当浮动一张图片或者其他元素时&#xff0c;浏览器会将浮动元素往上方推&#xff0c;直到它碰到父元素的内边界。后面的元素不再认为浮动元素在文档流中位于它的前面了&#xff0c;因为它就会占…

gitlab搭建配置;ssh配置;

1.centos7上搭建gitlab&#xff0c;过程略&#xff1b; 命令&#xff1a;gitlab-ctl [start] [stop] [restart] [reconfigure] [tail] 查看gtilab日志 [status] 查看gitlab运行状态信息 2.修改默认ip端口&#xff1a; vim /etc/gitlab/gitlab.rb &#xff1b; external_url h…

5月学习总结(Ant-Design,mustache,require.js,grunt)

一、Ant-Design学习 因为Ant-Design是基于React实现的&#xff0c;之前自己也学过一段时间的React&#xff0c;对React还是相对比较熟悉的&#xff0c;在学习Ant-Design也还不算吃力。 最开始是从源码看起&#xff0c;从最简单的Icon组件看的&#xff0c;然后连续看了几个组件就…

使用NoSQLUnit测试Spring Data Neo4j应用程序

Spring Data Neo4j是Spring Data项目中的项目&#xff0c;它提供了Spring编程模型的扩展&#xff0c;用于编写使用Neo4j作为图形数据库的应用程序。 要使用NoSQLUnit为Spring Data Neo4j应用程序编写测试&#xff0c;除了考虑Spring Data Neo4j在图形节点和关系中使用一种称为t…

家用计算机历史记录,教您如何查看电脑使用记录

很多朋友想查看自己之前使用过的文件或者文档来查询资料&#xff0c;或者是想看电脑是否被人使用过&#xff0c;但是&#xff0c;如何查看电脑使用记录呢&#xff1f;下面系统之家小编教大家查看电脑使用记录小技巧&#xff0c;不用担心找不到电脑使用记录。希望对大家有所帮助…

html5 图片上传 预览

<html><body><fieldset> <legend>测试</legend> <div class"form-group"> <div class"img-preview rl"> <form id"index_form1" name"index_form1" role"form" method"p…

使用selenium前学习HTML(3)— 属性

<!--HTML标签可以拥有属性&#xff0c;属性提供元素的更多的信息&#xff1b;属性总是以名称/值对的形式出现&#xff0c;比如&#xff1a;name"value"。属性总是在 HTML 元素的开始标签中规定。 --><!DOCTYPE html> <html lang"en"> &l…