如何使用 WebSocket + Jackson 在先後端之間交換 JSON 數據

文章首發於公衆號【大數據學徒】,感興趣請搜索 dashujuxuetu 或者文末掃碼關注。javascript

我正在用 Jetty 開發本身的一個玩具項目,在這個項目中,涉及到使用 WebSocket 在先後端之間交換 JSON 數據,本文對此作一個總結。前端

內容提要:java

  1. 環境說明
  2. 瀏覽器向服務器發送 JSON
  3. 服務器向瀏覽器發送 JSON

代碼已上傳至 github:github.com/iamabug/sun…git

1. 環境說明

JDK 版本:1.8github

瀏覽器:Chrome後端

Jackson 版本:2.10.1瀏覽器

開發工具:IntelliJ IDEA + Maven 插件服務器

須要添加 jackson 依賴:app

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.1</version>
</dependency>
複製代碼

2. 瀏覽器向服務器發送 JSON

分兩步:瀏覽器發送數據和服務器接收數據函數

瀏覽器發送

JavaScript 代碼以下:

var ws = new WebSocket("ws://localhost:12345/ws/kafka/dummy")
msg = {
    "type": "...",
    "data": {
      ...
    }
}

ws.onopen = function(e) {
    ws.send(JSON.stringify(msg))
}
複製代碼

能夠看到,這裏使用了 WebSocket 來發送數據,msg 是須要發送的數據,裏面包含了 typedata 兩個字段,在發送以前只須要調用一下 JSON.stringify() 便可。

服務器接收

在服務器端定義了 Message 類來接收數據,Message 類的部門定義以下:

public class Message {
  public enum type {
    ...
  }
  public TYPE type;
  public Map<String, Object> data = new HashMap<>();
  public Message put(String k, Object v) {
    data.put(k, v);
    return this;
  }
  // 省略 getter 和 setter 方法
	// 注意:空構造函數不可省略
  public Message() {}
}
複製代碼

注意,若是沒有空構造函數,會報以下異常:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `iamabug.common.Message` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"type":"ERROR_INFO","data":null}"; line: 1, column: 2]
複製代碼

在處理 onWebSocketText(String message) 方法內對消息進行反序列化:

// 序列化和發序列化都經過 ObjectMapper 來實現
Message msg = new ObjectMapper().readValue(message, Message.class);
複製代碼

這樣 msg 變量中存儲的就是前端發送來的數據。

3. 服務器向瀏覽器發送 JSON

也分爲兩步:服務器發送數據和瀏覽器接收數據

服務器發送

代碼以下:

Message resp = new Message(Message.TYPE.KAFKA_MESSAGES);
resp.put("messages", List.of("first message", "second message"));
resp.put("total", 2);
client.sendString(new ObjectMapper().writeValueAsString(resp));
複製代碼

首先準備好要發送的數據 resp,而後調用 ObjectMapperwriteValueAsString() 方法實現序列化,最後調用 Jetty WebSocket 的客戶端對象的 sendString() 方法將數據發送。

瀏覽器接收

代碼以下:

// ws 是一個 WebSocket 對象
ws.onmessage = function(e) {
  // 反序列化
  resp = JSON.parse(e.data)
  // 輸出驗證
  alert(resp.type)
}
複製代碼

很是簡潔,驗證截圖:

其中 KAFKA_MESSAGESMESSAGE 的一種類型。

歡迎交流討論,吐槽建議,分享收藏。

勤學似春起之苗,不見其增,日有所長
輟學如磨刀之石,不見其損,日有所虧
關注【大數據學徒】,用技術乾貨助你日有所長

大數據學徒
相關文章
相關標籤/搜索