赞
踩
在创建聊天应用的基础上,我写了一篇关于服务器和浏览器之间的WebSocket通信的文章。用 Java 实现服务器,用 javascript 实现客户端。
[过去关于套接字通信的文章] ・使用 Java 和 JavaScript与 Web 浏览器进行套接字通信① ・使用 Java 和 JavaScript 与 Web 浏览器进行套接字通信②
这一次,我们将在修改聊天应用程序的同时学习“如何处理 JSON 数据”。您还将了解“通过套接字通信发送和接收 JSON 数据”。
在本文中,我将主要描述如何处理 JSON。有关套接字通信的说明,请参阅过去的文章和 google 页面。⇒ 用 Java 实现服务器程序,用 JavaScript 实现客户端程序。
http://www.tohoho-web.com/ex/json.html 示例:{" name ":" Tanaka "," age ": 26}
以关联数组的形式保存值的事物。简而言之,如果你把它想象成一个**只是一个字符串**,就很容易理解了。(虽然不是真的)细节被省略。
JSON 数据可以在 JavaScript 中轻松处理。
对象⇒ JSON 使用JSON.stringify ()
方法。
Example of use
-
- var obj = {
- name: 'Taro',
- age: 30,
- area: 'Tokyo'
- }
- var json = JSON.stringify(obj);
- console.log(json);
Execution result
-
- {"name":"Taro Tanaka","age":30}
JSON.stringify (obj)
并将其分配给变量json
。(转换为 JSON)console.log (json)
。查看执行结果,可以看到关联数组格式的对象已经转换为 JSON 格式。⇒键和字符串用“”“括起来。数字保持裸露。
JSON ⇒ 对象 使用JSON.parse ()
方法。
Example of use
-
- var obj1 = {
- name: 'Taro',
- age: 30,
- area: 'Tokyo'
- }
- var json = JSON.stringify(obj1);
- //-----JSON data preparation so far-----
- var obj2 = JSON.parse(json);
- console.log(obj2);
- console.log(obj2.name);
Execution result
-
- {name: "Taro", age: 30, area: "Tokyo"}
- Taro
JSON.stringify (obj1)
并将其分配给变量json
。(转换为 JSON) ** ---------- 到目前为止 JSON 数据准备(与上一节中的编码相同) ---------- **JSON.parse (json)
并将其分配给变量ʻobj2`。(转换为对象)console.log (obj2)
。查看执行结果,可以看到 JSON 数据已经转换为对象。`obj1 (object) ⇒
json (JSON) ⇒ ʻobj2
(对象)
Java 对象指的是类,不像 JavaScript 那样容易创建。在转换 JSON 和对象时,需要提前创建一个类**,该类具有与 JSON 变量对应的属性。
如果您在 Java 中处理 JSON,建议使用外部库。⇒ 处理 JSON 的 Java 标准 API 也是可用的,但需要大量时间和精力。
以下是处理 JSON 的著名外部库。
基本用法类似,但这次我将使用“杰克逊”。有关如何使用其他库以及如何应用外部库的信息,请酌情查看参考页面或 google。
Object ⇒ JSON 使用writeValueAsString ()
ʻObjectMapper` 类的方法进行编码。
how to use
-
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(Object instance);
Example of use
-
- import java.io.IOException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- //A class with properties to convert to JSON
- class Info {
- public String name = "Taro Tanaka";
- public int age = 30;
- }
-
- //Class to perform encoding
- public class Main {
- public static void main(String[] args) {
- Info info = new Info();//Instantiate a class to convert to JSON
- ObjectMapper mapper = new ObjectMapper();//Create an instance of the ObjectMapper class
- try {
- //writeValueAsString()Encoding by method
- String script = mapper.writeValueAsString(info);
- System.out.println(script);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }

Execution result
-
- {"name":"Taro Tanaka","age":30}
Main
类来执行编码。class with
ObjectMapper ObjectMapper mapper = new ObjectMapper()`。mapper.writeValueAsString (info)
。这时候就需要用try和catch来处理错误了。System.out.println (script)
。查看执行结果,可以看到对象类已经转换为 JSON 格式。每个属性的变量名称和值存储为一对。
JSON ⇒ 对象 使用readValue ()
ʻObjectMapper` 类的方法进行解码。
how to use
-
- ObjectMapper mapper = new ObjectMapper();
- mapper.readValue(JSON data,Object class.class);
Example of use
-
- import java.io.IOException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- //A class with properties that are converted from JSON
- class Info {
- public String name;
- public int age;
- }
-
- //Class to perform decoding
- public class Main {
- public static void main(String[] args) {
- String script = "{ \"name\":\"Taro Tanaka\", \"age\":30}";//Create JSON data as a string
- ObjectMapper mapper = new ObjectMapper();//Create an instance of the ObjectMapper class
- try {
- //readValue()Decoding by method
- Info info = mapper.readValue(script, Info.class);
- System.out.println(info.name);
- System.out.println(info.age);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }

Execution result
-
- Taro Tanaka
- 30
Main
类来执行解码。class with
ObjectMapper ObjectMapper mapper = new ObjectMapper()`。mapper.readValue (script, Info.class)
。这时候就需要用try和catch来处理错误了。System.out.println (info. ~)
。查看执行结果,可以看到 JSON 数据已经转换为对象类。解码后,可以通过访问指定对象的每个属性来获取值。
服务器程序:Java 客户端程序:JavaScript
描述进行socket通信时用JSON发送和接收的方法。由于 Java 和 JavaScript 的处理方式不同,我们将分别进行解释。
JavaScript 没有什么特别之处。如上所述,您可以通过JSON.stringify ()
方法和JSON.parse ()
方法轻松地在对象和 JSON 之间进行转换。如果客户端在发送前编码,接收后解码,则没有问题。
对象⇒ JSON
When sending
-
- var obj = { type:'A' , msg:'a' };
- var json = JSON.stringify(obj);
- socket.send(json);
JSON.stringify ()
使用该方法编码为 JSON 。send ()
使用WebSocket的方法发送JSON数据JSON ⇒ 对象
When receiving
-
- socket.onmessage = function(e) {
- var obj = JSON.parse(e.data);
- };
JSON.parse (e.data)
当使用 JSON 进行 Java 套接字通信时,它并不像 JavaScript 那样简单。⇒ 需要准备编码器、解码器和对象类。
对象⇒ JSON
通过套接字通信发送 JSON 数据时,请在发送前使用编码器将对象转换为 JSON。
通常sendText ()
发送文本数据时使用该sendObject ()
方法,但发送JSON时使用该方法。参数是一个对象,由编码器转换为 JSON,然后发送。
1. 创建一个要发送的对象
创建一个具有像普通类一样的属性的类。像往常一样描述构造函数、setter 和 getter。(没有它也可以转换。)
Object class
-
- public class JsonObj {
-
- private String type = "type1";
- private String msg = "msg1";
-
- //constructor
- public JsonObj() {}
-
- //Setter
- public void setType(String type) {this.type = type;}
- public void setMsg(String msg) {this.msg = msg;}
-
- //Getter
- public String getType() {return type;}
- public String getMsg() {return msg;}
- }

2. 创建编码器
编码器实现了`Encoder.Text class in the
javax.websocket package. (There is also the ʻEncoder.Binary
类,但是因为是处理二进制数据的类所以省略)
ʻEncoder.Text <> `generics 描述了要编码的对象类。
encoder
-
- import javax.websocket.EncodeException;
- import javax.websocket.Encoder;
- import javax.websocket.EndpointConfig;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- public class JsonEncoder implements Encoder.Text<JsonObj>{
-
- @Override//Initialization does nothing
- public void init(EndpointConfig config) {}
-
- @Override//Encoding process(Object → JSON)
- public String encode(JsonObj obj) throws EncodeException {
- ObjectMapper mapper = new ObjectMapper();
- String json = "";
- try {
- json = mapper.writeValueAsString(obj);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
- return json;
- }
-
- @Override//Do nothing to destroy
- public void destroy() {}
- }

`如果你继承了Encoder.Text`类,你需要重写以下方法。
destroy ()
: 编码器被破坏时的处理。基本上 ʻinit() and
destroy() do not have to do anything. In ʻencode (Object)
,将 ** 参数设置为 object ** 并指定 JSON ** 作为编码后的返回值。
3.注册编码器
@ServerEndpoint
-
- //Specify encoder class
- @ServerEndpoint(value = "/json" , encoders = JsonEncoder.class)
- public class JsonTest {
- //Omission
-
- //sendObject()The argument of is an object
- //Encoded before sending
- session.getAsyncRemote().sendObject(obj)
-
- //Omission
- }
使用编码器时,请在 中指定编码器类@ServerEndpoint ()
。通过此处指定,将由发送对象时指定的编码器转换为 JSON 数据。
-- sendObject (obj)
** ⇒ 编码过程 (obj → JSON) ⇒ 发送 **
JSON ⇒ 对象
通过socket通信接收JSON数据时,在接收前使用解码器将JSON转换为对象。
通常,作为`onMessage()`方法的参数作为String类型的字符串接收,但通过使用解码器,在接收之前进行解码处理,并作为对象接收。
1.创建目标对象
解码时,需要准备一个对象类,该对象类具有对应于 JSON 元素的属性。如果接收多个 JSON 时内容和格式不同,则必须为每个 JSON 准备多个对象类。
在编码的情况下,所有对象都可以转换成JSON随时发送,在解码的情况下,需要提前掌握接收到的JSON的内容,并在解码前准备对象类作为接收端口。
Object class
-
- public class JsonObj {
-
- private String type;
- private String msg;
-
- //constructor
- public JsonObj() {}
-
- //Setter
- public void setType(String type) {this.type = type;}
- public void setMsg(String msg) {this.msg = msg;}
-
- //Getter
- public String getType() {return type;}
- public String getMsg() {return msg;}
- }

2.创建解码器
解码器实现包Decoder.Text
中的类 javax.websocket
。(还有一个Decoder.Binary
类,但是因为是处理二进制数据的类所以省略了。)
在 的泛型中描述解码目的地的对象类Decoder.Text <>
。
Decoder
-
- import javax.websocket.DecodeException;
- import javax.websocket.Decoder;
- import javax.websocket.EndpointConfig;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- public class JsonDecoder implements Decoder.Text<JsonObj> {
-
- @Override//Initialization does nothing
- public void init(EndpointConfig config) {}
-
- @Override//Judgment of whether decoding is possible
- public boolean willDecode(String text) {
- return (text != null);
- }
-
- @Override//Decoding process(JSON → object)
- public JsonObj decode(String text) throws DecodeException {
- ObjectMapper mapper = new ObjectMapper();
- JsonObj obj = null;
- try {
- obj = mapper.readValue(text, JsonObj.class);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
- return obj;
- }
-
- @Override//Do nothing to destroy
- public void destroy() {}
- }

如果继承Decoder.Text
该类,则需要重写以下方法。
willDecode (String text)
:判断是否执行解码过程。decode (Object obj)
: 解码过程。destroy ()
: 解码器被破坏时的处理。基本上ʻinit() and
destroy() do not have to do anything. Set the ** argument of
willDecode() to JSON **, and if the return value is
true , execute the following decoding. If it is
false , it will not be decoded and the subsequent
@OnMessage methods will not be executed. In
decode()`,将**参数设置为JSON **并指定object **作为编码后的返回值。
3.注册解码器
@ServerEndpoint
-
- //Specify decoder class
- @ServerEndpoint(value = "/json" , decoders = JsonDecoder.class)
- public class JsonTest {
- //Omission
-
- //@Decoded before the OnMessage method
- @OnMessage
- public void onMessage(JsonObj obj , Session mySession) {
- }
-
- //Omission
- }
使用解码器时,请在 中指定解码器类@ServerEndpoint ()
。通过此处指定,将由接收数据时指定的解码器转换为对象。⇒@OnMessage
方法的参数是**对象类型**。(通常是字符串类型)
-** 接收 ⇒ 解码过程(JSON → obj) ⇒ ** @OnMessage
** 方法 **
修改Past中创建的聊天应用。
在 WebSocket 通信中,只有一个套接字用于接收数据。也就是说,因为是一次性的,所以即使有多个来源也无法区分。如果你能分辨,你必须分解字符串的内容来区分它们。无论如何要解码,处理JSON很方便。
其实接收方式有3种:1.Text 2.Binary 3.PingPong,但是由于我们这里只处理文本格式,所以我们认为只有一个socket。
JsonIndex.html
-
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>Send / receive JSON</title>
- <script type="text/javascript" src="JsonSocket.js"></script>
- </head>
- <body>
- <div
- style="width: 500px; height: 200px; overflow-y: auto; border: 1px solid #333;"
- id="show1"></div>
- <input type="text" size="80" id="msg1" name="msg1" />
- <input type="button" value="Send" onclick="sendMsg1();" />
- <p></p>
- <div
- style="width: 500px; height: 200px; overflow-y: auto; border: 1px solid #333;"
- id="show2"></div>
- <input type="text" size="80" id="msg2" name="msg2" />
- <input type="button" value="Send" onclick="sendMsg2();" />
- </body>
- </html>

观点
show1
和 show2
,文本框分别为msg1
和 msg2
。使用稍后描述的 JavaScript 文件操作这些。JsonSocket.js
-
- //Object creation for JSON
- var obj = { type:null , msg:null };
-
- //WebSocket object generation
- var wSck= new WebSocket("ws://localhost:8080/jsonTest/json");
-
- //Action when connecting socket
- wSck.onopen = function() {
- document.getElementById('show1').innerHTML += "Connected." + "<br/>";
- document.getElementById('show2').innerHTML += "I'm connected ~" + "<br/>";
- };
-
- //Action when receiving a message
- wSck.onmessage = function(e) {
- //Decode JSON data into an object
- var json = JSON.parse(e.data);
-
- //Change the execution content depending on the type value of JSON data
- if(json.type === 'msg1'){document.getElementById('show1').innerHTML += json.msg + "<br/>";}
- else if(json.type === 'msg2'){document.getElementById('show2').innerHTML += json.msg + "<br/>";}
- };
-
- //Send message 1
- var sendMsg1 = function(val) {
- var element = document.getElementById('msg1')
- obj.type = element.name;//Substitute the contents of the object
- obj.msg = element.value;
- var json = JSON.stringify(obj);//Encode object to JSON
- wSck.send(json);//Send JSON
- element.value = "";//Clear the contents
- };
-
- //Send message 2
- var sendMsg2 = function(val) {
- var element = document.getElementById('msg2');
- obj.type = element.name;
- obj.msg = element.value;
- var json = JSON.stringify(obj);
- wSck.send(json);
- element.value = "";
- };

观点
JsonTest.java
-
- package jsonTest;
-
- import java.io.IOException;
- import java.util.Set;
- import java.util.concurrent.CopyOnWriteArraySet;
-
- import javax.websocket.OnClose;
- import javax.websocket.OnMessage;
- import javax.websocket.OnOpen;
- import javax.websocket.Session;
- import javax.websocket.server.ServerEndpoint;
-
- //Describe the decoder and encoder in the arguments
- @ServerEndpoint(value = "/json" , decoders = JsonDecoder.class , encoders = JsonEncoder.class)
- public class JsonTest {
-
- private static Set<Session> user = new CopyOnWriteArraySet<>();
-
- @OnOpen
- public void onOpen(Session mySession) {
- System.out.println("connect ID:"+mySession.getId());
- user.add(mySession);
- }
-
- //Decoded before this method
- @OnMessage
- public void onMessage(JsonObj obj , Session mySession) {
- for (Session user : user) {
- user.getAsyncRemote().sendObject(obj);//What you send is an object(Encoded before sending)
- System.out.println(user.getId()+"Second"+mySession.getId()+"I sent the second message!");
- }
- if(obj.getMsg().equals("bye")) {onClose(mySession);}
- }
-
- @OnClose
- public void onClose(Session mySession) {
- System.out.println("disconnect ID:"+mySession.getId());
- user.remove(mySession);
- try {
- mySession.close();
- } catch (IOException e) {
- System.err.println("An error has occurred: " + e);
- }
- }
- }

观点
@ServerEndpoint
。@OnMesaage
并将 JSON 转换为对象。⇒@OnMesaage
方法的参数是ʻObj` 类型。sendObject (obj)
方法发送对象时,会在发送到客户端之前执行指定的编码器,并将对象转换为 JSON。sendText ()
发送字符串时使用,sendObject ()
发送对象时使用。JsonObj.java
-
- package jsonTest;
-
- public class JsonObj {
-
- private String type;
- private String msg;
-
- //constructor
- public JsonObj() {}
-
- //Setter
- public void setType(String type) {this.type = type;}
- public void setMsg(String msg) {this.msg = msg;}
-
- //Getter
- public String getType() {return type;}
- public String getMsg() {return msg;}
- }

观点
type
和 msg
。⇒ 创建一个对应于客户端程序对象(接收到的 JSON)的类。type
属性值判断来源。JsonEncoder.java
-
- package jsonTest;
-
- import javax.websocket.EncodeException;
- import javax.websocket.Encoder;
- import javax.websocket.EndpointConfig;
-
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- public class JsonEncoder implements Encoder.Text<JsonObj>{
-
- @Override//Initialization does nothing
- public void init(EndpointConfig config) {}
-
- @Override//Encoding process(Object → JSON)
- public String encode(JsonObj obj) throws EncodeException {
- ObjectMapper mapper = new ObjectMapper();
- String json = "";
- try {
- json = mapper.writeValueAsString(obj);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
- return json;
- }
-
- @Override//Do nothing to destroy
- public void destroy() {}
- }
-

观点
writeValueAsString ()
ʻObjectMapper` 类的方法进行编码。- package jsonTest;
-
- import javax.websocket.DecodeException;
- import javax.websocket.Decoder;
- import javax.websocket.EndpointConfig;
-
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- public class JsonDecoder implements Decoder.Text<JsonObj> {
-
- @Override//Initialization does nothing
- public void init(EndpointConfig config) {}
-
- @Override//Judgment of whether decoding is possible
- public boolean willDecode(String text) {
- return (text != null);
- }
-
- @Override//Decoding process(JSON → object)
- public JsonObj decode(String text) throws DecodeException {
- ObjectMapper mapper = new ObjectMapper();
- JsonObj obj = null;
- try {
- obj = mapper.readValue(text, JsonObj.class);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
- return obj;
- }
-
- @Override//Do nothing to destroy
- public void destroy() {}
- }

观点
Decoder.Text <JsonObj>
.decode ()
方法的参数是一个字符串(JSON),返回值是一个对象。readValue ()
ʻObjectMapper` 类的方法进行编码。JsonIndex.html
在 Chrome 中 执行。
聊天字段已增加到两个。您可以在每个聊天字段中独立发送和接收。⇒ 多路径的实现完成。
现在它很长,描述客户端和服务器上发生的事情。
@OnMessage
以解码的对象作为参数执行该方法。sendObject ()
。type
属性值确定来源并向每个来源显示一条消息。-如果接收到未知的JSON数据,会因为没有准备好对应的对象类而出错。⇒有人支持它,所以我可能会尽快检查它。它看起来相当复杂。
- 接收多种 JSON 数据时不支持。⇒ 好像没那么难。可以通过增加解码器和对象类来支持JSON的内容。
- 不知道应该创建什么样的对象类来支持嵌套的 JSON。⇒ 如果你google,它会出来,如果有必要,检查一下。
- 由于对二进制数据的处理不是很了解,所以不支持二进制数据的发送和接收。⇒必要时检查,例如发送和接收图像。
它比我预期的要复杂。我后悔了,因为它变长了。我应该总结得更多。
在Java中处理JSON,使用外部库和准备一个对象类是很麻烦的。使用 JavaScript,它以一行结尾。
Java socket通信中处理JSON时,有编码类和解码类方便吗?必须准备一个编码器类和一个解码器类是很麻烦的。
这很麻烦,但如果你想使用 JSON,你就无能为力了。对如何在 Java 中处理 JSON 有更深入的了解是件好事。看来您可以在个人生产级别使用它。
-使用 JavaScript编码和解码 JSON 数据 -用Java 编码和解码 JSON 数据(Jackson) -用 Java编码和解码 JSON 数据(Jackson 专业化) -用 Java编码和解码 JSON 数据(Jackson 等人) -发送/接收 JSON in Socket Communication -在 Socket 通信中发送/接收 JSON(多对象)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。