Skip to main content

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:

pom.xml
<!-- 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:

  1. Create a custom JSON codec class and implement DataCodec.
  2. 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:

class OneClient {
static void main() {
DataCodecManager.setDataCodec(new JsonDataCodec());

new ClientRunOne()
...
.startup();
}
}