preface
Before we talk about this, let's take a look at the relevant background knowledge.
Introduction to RPC
RPC is short for Remote Procedure Call. Remote service call. Simply put, one node provides services (called server) and one node consumes services (client).
RPC communication mode
The communication protocol between the server and client of PRC is TCP/IP. However, you must have doubts. How does the client know the class definition in the service provided by the server? The answer is serialization and deserialization. The function of serialization: convert the structure class information into bytecode for transmission between different services. Deserialization: restore the received information into structure information according to the Convention.
Practical analysis
Emerald flower above
Don't say much. Go straight to the figure above and code it.
In the figure above, the client provides a service that can query the combat effectiveness of the role, which is packaged for the client to view and consume. However, the server secretly upgraded the second-party package version to 2.0 without telling the client. There are few cruel words. It belongs to yes.
Code on Cuihua
Enumeration class for version 1.0. It can be seen that the monkey king is still better than the third prince, ranking in the front.
1.0
public enum RoleEnum { WU_KONG(0,"Sun WuKong"), NE_ZHA(1,"nezha"); int code; String desc; RoleEnum(int code, String desc) { this.code = code; this.desc = desc; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
OK. Let's simulate serialization and deserialization. Note: in RPC services, enumeration classes are generally serialized into names, and deserialization is performed through valueOf().
// Client, serialize RoleEnum. String jsonString = JSON.toJSONString(RoleEnum.values()); System.out.println("serialize"); System.out.println(jsonString); //Deserialization List<RoleEnum> roleEnumList = JSON.parseArray(jsonString, RoleEnum.class); System.out.println("Deserialization"); roleEnumList.stream().forEach(e -> System.out.println(e.toString()));
Console after operation:
serialize ["WU_KONG","NE_ZHA"] Deserialization WU_KONG NE_ZHA
As you can see. When it is version 1.0, the client can correctly analyze who is the first.
2.0
OK. Next, the server secretly added a heavyweight player, Zhu Bajie, to the challenge arena.
Let's look at enumeration classes
public enum RoleEnum { WU_KONG(0,"Sun WuKong"), NE_ZHA(1,"nezha"), BA_JIE(2,"Zhu Bajie"); int code; String desc; RoleEnum(int code, String desc) { this.code = code; this.desc = desc; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
I'm lazy here. After the server upgrades the second-party package version 2.0, the serialized RoleEnum form is:
serialize ["WU_KONG","NE_ZHA","BA_JIE"]
OK, start deserialization
public class Test01 { public static void main(String[] args) { // Client, serialize RoleEnum. //String jsonString = JSON.toJSONString(RoleEnum.values()); System.out.println("serialize"); String jsonString = "[\"WU_KONG\",\"NE_ZHA\",\"BA_JIE\"]"; System.out.println(jsonString); //Deserialization List<RoleEnum> roleEnumList = JSON.parseArray(jsonString, RoleEnum.class); System.out.println("Deserialization"); roleEnumList.stream().forEach(e -> System.out.println(e.toString())); } }
Start the challenge arena and execute... Eh, why did you report wrong.
serialize ["WU_KONG","NE_ZHA","BA_JIE"] Deserialization WU_KONG NE_ZHA Exception in thread "main" java.lang.NullPointerException at com.pinfine.test.Test01.lambda$main$0(Test01.java:26) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380) at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) at com.pinfine.test.Test01.main(Test01.java:26)
It can be seen from the error message that a null pointer appears. That is, the error occurred when calling the valueOf() method of the enumeration class. It's because Bajie only provides a 2.0 second-party package on the server, but the client is still version 1.0. Naturally, there is no Bajie in it. According to the name, the Bajie building can not be parsed naturally.
proposal
1. When RPC provides services, it is forbidden to return enumeration classes as parameters or encapsulated in POJO objects.
2. For enumeration classes, they can be encapsulated into an object instead.