PB/JSON Data Protocol Extension
Introduction
The framework supports different business data protocols (such as protobuf and JSON) with the same business code and no code changes, and it supports extension. Switching protocol implementations in the framework is simple and only requires one line of code.
The framework currently has built-in codec support only for jprotobuf business data protocols. Now we will learn how to extend a JSON codec. After this section, you will be able to extend codecs for any business data protocol.
Extend JSON Codec
Now we use Jackson to extend a JSON codec.
Add Jackson:
<!-- https://mvnrepository.com/artifact/tools.jackson.core/jackson-databind -->
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>3.0.0</version>
</dependency>
Create a custom JSON codec class and implement the DataCodec interface.
@Slf4j
public class JsonDataCodec implements DataCodec {
@Override
public byte[] encode(Object data) {
if (Objects.isNull(data)) {
return CommonConst.emptyBytes;
}
try {
return JsonKit.objectMapper.writeValueAsBytes(data);
} catch (Throwable e) {
log.error(e.getMessage(), e);
}
return CommonConst.emptyBytes;
}
@Override
public <T> T decode(byte[] data, Class<T> dataClass) {
if (ArrayKit.isEmpty(data)) {
return null;
}
try {
return JsonKit.objectMapper.readValue(data, dataClass);
} catch (Throwable e) {
log.error(e.getMessage(), e);
}
return null;
}
}
@Slf4j
@UtilityClass
public class JsonKit {
final ObjectMapper objectMapper = JsonMapper.builder()
.enable(SerializationFeature.INDENT_OUTPUT)
.build();
public String toJson(Object object) {
try {
return objectMapper.writeValueAsString(object);
} catch (JacksonException e) {
log.error(e.getMessage(), e);
}
return "{}";
}
}
- code 3: set JSON codec.
class OneApplication {
static void main() {
DataCodecManager.setDataCodec(new JsonDataCodec());
...
new RunOne()
...
.startup();
}
}
Only two steps are needed to complete JSON extension:
- Create a custom JSON codec class and implement
DataCodec. - Register it in
DataCodecManager.
Action Business Code
Let's first look at an action business-code snippet.
@ActionController(19)
public class JsonAction {
@ActionMethod(1)
public HelloMessage hello(HelloMessage message) {
message.name = message.name + ",hello json";
return message;
}
}
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class HelloMessage {
public String name;
}
You may notice that HelloMessage still has the ProtobufClass annotation. Do not worry, this does not affect runtime.
Here, ProtobufClass has no effect because we are currently using a JSON codec.
In short, this annotation is optional in this case.
If ProtobufClass is optional here, why keep it?
The point is: if your previous project used the default jprotobuf codec,
you can switch to JSON format without changing business code.
That means one set of business code can support different data protocols without modification.
Notes and Considerations
The default framework codec is jprotobuf. If you use a custom codec, the requester must use the same data-protocol codec as the server, for example:
- Game client.
- Simulation client.
class OneClient {
static void main() {
DataCodecManager.setDataCodec(new JsonDataCodec());
new ClientRunOne()
...
.startup();
}
}