javascript
使用Java WebSockets,JSR 356和JSON映射到POJO的
因此,我一直在研究Tyrus (JSR 356 WebSocket for Java規范的參考實現)。 因為我一直在尋找測試工具,所以我對在Java中同時運行客戶端和服務器端感興趣。 因此,恐怕此博客文章中沒有HTML5。
在此示例中,我們想來回發送JSON,因為我像這樣老式,所以我希望能夠綁定到POJO對象。 我將為此使用Jackson,因此我的Maven文件如下所示:
因此,我們需要做的第一件事就是定義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的版本進行比較會很有趣。 也許是另一天的事情。
翻譯自: https://www.javacodegeeks.com/2013/05/using-java-websockets-jsr-356-and-json-mapped-to-pojos.html
總結
以上是生活随笔為你收集整理的使用Java WebSockets,JSR 356和JSON映射到POJO的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019千牛卖家版官方下载电脑版(千牛卖
- 下一篇: 电脑cpu发热降频怎么办(电脑过热降频怎