被@OnMessage修飾的函數是用來接收和返回客戶端發送過來的消息的,接收的參數和返回值能夠爲Java對象。css
要使@OnMessage修飾的函數能夠處理Java對象,須要對端點類設置decoders和encoders,其中decoders類須要實現接口javax.websocket.Decoder.Text<User>,而encoders類須要實現接口javax.websocket.Encoder.Text<User>,下面是具體例子:html
1.點擊鏈接按鈕與服務端鏈接;java
2.點擊發送按鈕發送一個json對象到服務端;jquery
3.服務端返回一個java對象的json字符串到客戶端;web
4.關閉與服務端的鏈接;數據庫
<dependencies> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/javax/javaee-api --> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api --> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.20</version> </dependency> </dependencies>
實體類是一個POJO對象,叫User,具備兩個屬性Id和Name,下面是實體類的代碼:json
package cn.net.bysoft.websocketapp.lesson3; public class User implements java.io.Serializable { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
轉換類有兩個,分別是UserDecoder和UserEncoder。bootstrap
注意:UserDecoder類中,有一個willDecode方法,該方法優先於decode被調用。這是爲了使你有一個跳過解碼消息的機會。api
下面是具體代碼:websocket
package cn.net.bysoft.websocketapp.lesson3; import javax.websocket.DecodeException; import javax.websocket.EndpointConfig; import com.alibaba.fastjson.JSON; public class UserDecoder implements javax.websocket.Decoder.Text<User> { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void init(EndpointConfig arg0) { // TODO Auto-generated method stub } @Override public User decode(String user) throws DecodeException { return JSON.parseObject(user, User.class); } @Override public boolean willDecode(String arg0) { return true; } }
package cn.net.bysoft.websocketapp.lesson3; import javax.websocket.EncodeException; import javax.websocket.EndpointConfig; import com.alibaba.fastjson.JSON; public class UserEncoder implements javax.websocket.Encoder.Text<User> { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void init(EndpointConfig arg0) { // TODO Auto-generated method stub } @Override public String encode(User user) throws EncodeException { return JSON.toJSONString(user); } }
在@ServerEndpoint中指定了decoders和encoders,具體代碼以下:
package cn.net.bysoft.websocketapp.lesson3; import java.io.IOException; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/objecthandle", decoders = { UserDecoder.class }, encoders = { UserEncoder.class }) public class ObjectHandle { private Session ws_session; @OnOpen public void onOpen(Session ws_session) { // 設置session,並記錄創建鏈接時間 this.ws_session = ws_session; // 通知客戶端鏈接成功 this.sendMessage("success:opened."); } @OnMessage public User onMessage(User user) { // 作點處理返回給客戶端 user.setName("yes, jack"); return user; } @OnError public void onError(Throwable t) { // 發生異常時,若是鏈接仍是打開狀態,則通知客戶端錯誤信息 if (ws_session.isOpen()) { this.sendMessage("warning:Error:" + t.getMessage()); } } @OnClose public void onClose() { // 關閉鏈接時,須要作的事情在該函數內完成,例如關閉數據庫鏈接等 } private void sendMessage(String message) { try { // 以同步的方式向客戶端發送消息 ws_session.getBasicRemote().sendText(message); } catch (IOException e) { System.out.println("Method: sendMessage, Error closeing session " + e.getMessage()); } } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css"> <!-- 可選的Bootstrap主題文件(通常不用引入) --> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap-theme.min.css"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <h1>WebSocket發送JAVA對象</h1> <div class="row"> <div class="col-md-12"> <p> <button type="button" class="btn btn-primary" onclick="open_connection()">打開鏈接</button> <button type="button" class="btn btn-danger" onclick="closeClient()">關閉鏈接</button> </p> </div> </div> <div class="row"> <form class="form-inline" role="form"> <div class="col-md-12"> <div class="form-group"> <div class="input-group"> <div class="input-group"> <span class="input-group-addon"><span class="glyphicon glyphicon-send"></span></span> <input id="txtMessage" value="{id:1, name: jack}" readonly="readonly" type="text" class="form-control" placeholder="Send Message"> </div> <button type="button" class="btn btn-info" onclick="messageClick()">發送消息</button> </div> </div> </div> </form> </div> <div class="row"> <div class="col-md-12"> <p id="output"> <br> </p> </div> </div> </div> </body> <script> var lifecycle_websocket = null; function init() { output = document.getElementById("output"); } function dispose() { lifecycle_websocket.close(); lifecycle_websocket = null; } function open_connection() { if (lifecycle_websocket == null) { lifecycle_websocket = new WebSocket( "ws://localhost:8080/websocketapp/objecthandle"); lifecycle_websocket.onmessage = function(evt) { displayMessage(evt.data); } lifecycle_websocket.onclose = function(evt) { displayMessage(evt.data); } lifecycle_websocket.onerror = function(evt) { displayMessage(evt.data); } } } function messageClick() { var user = { id: 1, name: "jack" } send_message(JSON.stringify(user)); } function closeClient() { lifecycle_websocket.close(); displayMessage("danger:client closed.") } function send_message(message) { lifecycle_websocket.send(message); } function displayMessage(message) { var pre = document.createElement("p"); if(message.indexOf('{') == 0) { // 調用bootstrap樣式 pre.className = "text-info"; pre.innerHTML = message; output.appendChild(pre); } else { var flag = message.substring(0, message.indexOf(':')); var data = message.substring(message.indexOf(':') + 1); // 調用bootstrap樣式 pre.className = "text-" + flag; pre.innerHTML = data; output.appendChild(pre); } } window.addEventListener("load", init, false); window.addEventListener("unload", dispose, false); </script> </html>