Fix hard dependency on protobuf on pojo mode (#13012)

This commit is contained in:
icodening 2023-09-06 21:28:14 +08:00 committed by GitHub
parent dad3b070cd
commit 99ba6e3037
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 17 deletions

View File

@ -93,9 +93,6 @@ public class JsonCodec implements HttpMessageCodec {
List<Object> result = new ArrayList<>();
try {
try {
if (targetTypes.length == 1) {
return new Object[]{this.decode(dataInputStream, targetTypes[0])};
}
int len;
byte[] data = new byte[4096];
StringBuilder builder = new StringBuilder(4096);

View File

@ -89,13 +89,30 @@ public class JsonPbCodec implements HttpMessageCodec {
@Override
public Object[] decode(InputStream dataInputStream, Class<?>[] targetTypes) throws DecodeException {
try {
if (hasProtobuf(targetTypes)) {
//protobuf only support one parameter
return new Object[]{decode(dataInputStream, targetTypes[0])};
}
} catch (Throwable e) {
throw new DecodeException(e);
}
return jsonCodec.decode(dataInputStream, targetTypes);
}
private boolean isProtobuf(Class<?> targetType) {
private static boolean isProtobuf(Class<?> targetType) {
if (targetType == null) {
return false;
}
return Message.class.isAssignableFrom(targetType);
}
private static boolean hasProtobuf(Class<?>[] classes){
for (Class<?> clazz : classes) {
if (isProtobuf(clazz)) {
return true;
}
}
return false;
}
}

View File

@ -27,6 +27,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOBUF_MESSAGE_CLASS_NAME;
/**
* compatible low version.
* version < 3.3
@ -64,11 +66,8 @@ public class GrpcCompositeCodec implements HttpMessageCodec {
try {
int compressed = 0;
outputStream.write(compressed);
if (data instanceof Message) {
int serializedSize = ((Message) data).getSerializedSize();
//write length
writeLength(outputStream, serializedSize);
protobufHttpMessageCodec.encode(outputStream, data);
if (isProtobuf(data)) {
ProtobufWriter.write(protobufHttpMessageCodec, outputStream, data);
return;
}
//wrapper
@ -80,7 +79,7 @@ public class GrpcCompositeCodec implements HttpMessageCodec {
@Override
public Object decode(InputStream inputStream, Class<?> targetType) throws DecodeException {
if (isProtobuf(targetType)) {
if (isProtoClass(targetType)) {
return protobufHttpMessageCodec.decode(inputStream, targetType);
}
return wrapperHttpMessageCodec.decode(inputStream, targetType);
@ -94,13 +93,6 @@ public class GrpcCompositeCodec implements HttpMessageCodec {
return HttpMessageCodec.super.decode(inputStream, targetTypes);
}
private boolean isProtobuf(Class<?> targetType) {
if (targetType == null) {
return false;
}
return Message.class.isAssignableFrom(targetType);
}
private static void writeLength(OutputStream outputStream, int length) {
try {
outputStream.write(((length >> 24) & 0xFF));
@ -121,4 +113,40 @@ public class GrpcCompositeCodec implements HttpMessageCodec {
public boolean support(String contentType) {
return contentType.startsWith(MEDIA_TYPE.getName());
}
private static boolean isProtobuf(Object data) {
if (data == null) {
return false;
}
return isProtoClass(data.getClass());
}
private static boolean isProtoClass(Class<?> clazz) {
while (clazz != Object.class && clazz != null) {
Class<?>[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) {
for (Class<?> clazzInterface : interfaces) {
if (PROTOBUF_MESSAGE_CLASS_NAME.equalsIgnoreCase(clazzInterface.getName())) {
return true;
}
}
}
clazz = clazz.getSuperclass();
}
return false;
}
/**
* lazy init protobuf class
*/
private static class ProtobufWriter {
private static void write(HttpMessageCodec codec, OutputStream outputStream, Object data) {
int serializedSize = ((Message) data).getSerializedSize();
//write length
writeLength(outputStream, serializedSize);
codec.encode(outputStream, data);
}
}
}