Dubbo——Dubbo协议整合Jackson序列化解决方案
Posted Starzkg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dubbo——Dubbo协议整合Jackson序列化解决方案相关的知识,希望对你有一定的参考价值。
环境配置
spring boot 2.6.3
spring cloud 2021.0.1
spring cloud alibaba 2021.0.1.0
nacos server 2.0.4
dubbo 2.7.15
官方文档
序列化扩展:SPI扩展实现-序列化扩展
多协议配置:配置多协议
已知扩展
解决方案
源代码:https://gitee.com/myzstu/auth/tree/master/auth-core/src/main/java/club/zstuca/myzstu/dubbo/serialize/jackson
Maven 项目结构:
src
|-main
|-java
|-com
|-xxx
|-XxxSerialization.java (实现Serialization接口)
|-XxxObjectInput.java (实现ObjectInput接口)
|-XxxObjectOutput.java (实现ObjectOutput接口)
|-resources
|-META-INF
|-dubbo
|-org.apache.dubbo.common.serialize.Serialization (纯文本文件,内容为:xxx=com.xxx.XxxSerialization)
JacksonSerialization.java:
package club.zstuca.myzstu.dubbo.serialize.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.Serialization;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Jackson serialization implementation
*
* <pre>
* e.g. <dubbo:protocol serialization="jackson" />
* </pre>
*
* @author shentuzhigang
* @date 2022/3/19 15:00
*/
public class JacksonSerialization implements Serialization
private final byte JACKSON_SERIALIZATION_ID = 31;
private static ObjectMapper objectMapper = new ObjectMapper();
public static synchronized void setObjectMapper(ObjectMapper objectMapper)
JacksonSerialization.objectMapper = objectMapper;
@Override
public byte getContentTypeId()
return JACKSON_SERIALIZATION_ID;
@Override
public String getContentType()
return "text/json";
@Override
public ObjectOutput serialize(URL url, OutputStream output) throws IOException
return new JacksonObjectOutput(objectMapper, output);
@Override
public ObjectInput deserialize(URL url, InputStream input) throws IOException
return new JacksonObjectInput(objectMapper, input);
JacksonObjectInput.java:
package club.zstuca.myzstu.dubbo.serialize.jackson;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.dubbo.common.serialize.ObjectInput;
import java.io.*;
import java.lang.reflect.Type;
/**
* Jackson object input implementation
*
* @author shentuzhigang
* @date 2022/3/19 15:07
*/
public class JacksonObjectInput implements ObjectInput
private final ObjectMapper objectMapper;
private final BufferedReader reader;
public JacksonObjectInput(InputStream input)
this(new ObjectMapper(), input);
public JacksonObjectInput(ObjectMapper objectMapper, InputStream input)
this(objectMapper, new InputStreamReader(input));
public JacksonObjectInput(ObjectMapper objectMapper, Reader reader)
this.objectMapper = objectMapper;
this.reader = new BufferedReader(reader);
@Override
public boolean readBool() throws IOException
return read(boolean.class);
@Override
public byte readByte() throws IOException
return read(byte.class);
@Override
public short readShort() throws IOException
return read(short.class);
@Override
public int readInt() throws IOException
return read(int.class);
@Override
public long readLong() throws IOException
return read(long.class);
@Override
public float readFloat() throws IOException
return read(float.class);
@Override
public double readDouble() throws IOException
return read(double.class);
@Override
public String readUTF() throws IOException
return read(String.class);
@Override
public byte[] readBytes() throws IOException
return readLine().getBytes();
@Override
public Object readObject() throws IOException, ClassNotFoundException
return objectMapper.readTree(readLine());
@Override
public <T> T readObject(Class<T> cls) throws IOException, ClassNotFoundException
return read(cls);
@Override
public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException
JavaType javaType = TypeFactory.defaultInstance().constructType(type);
return objectMapper.readValue(readLine(), javaType);
private String readLine() throws IOException, EOFException
String line = reader.readLine();
if (line == null || line.trim().length() == 0)
throw new EOFException();
return line;
private <T> T read(Class<T> cls) throws IOException
String json = readLine();
return objectMapper.readValue(json, cls);
JacksonObjectOutput.java:
package club.zstuca.myzstu.dubbo.serialize.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.dubbo.common.serialize.ObjectOutput;
import java.io.*;
/**
* Jackson object output implementation
*
* @author shentuzhigang
* @date 2022/3/19 15:06
*/
public class JacksonObjectOutput implements ObjectOutput
private final ObjectMapper objectMapper;
private final PrintWriter writer;
public JacksonObjectOutput(OutputStream output)
this(new ObjectMapper(), output);
public JacksonObjectOutput(ObjectMapper objectMapper, OutputStream out)
this(objectMapper, new OutputStreamWriter(out));
public JacksonObjectOutput(ObjectMapper objectMapper, Writer writer)
this.objectMapper = objectMapper;
this.writer = new PrintWriter(writer);
@Override
public void writeBool(boolean v) throws IOException
writeObject(v);
@Override
public void writeByte(byte v) throws IOException
writeObject(v);
@Override
public void writeShort(short v) throws IOException
writeObject(v);
@Override
public void writeInt(int v) throws IOException
writeObject(v);
@Override
public void writeLong(long v) throws IOException
writeObject(v);
@Override
public void writeFloat(float v) throws IOException
writeObject(v);
@Override
public void writeDouble(double v) throws IOException
writeObject(v);
@Override
public void writeUTF(String v) throws IOException
writeObject(v);
@Override
public void writeBytes(byte[] v) throws IOException
writer.println(new String(v));
@Override
public void writeBytes(byte[] v, int off, int len) throws IOException
writer.println(new String(v));
@Override
public void writeObject(Object obj) throws IOException
writer.write(objectMapper.writeValueAsString(obj));
writer.println();
writer.flush();
@Override
public void flushBuffer() throws IOException
writer.flush();
META-INF/dubbo/org.apache.dubbo.common.serialize.Serialization:
jackson=club.zstuca.myzstu.dubbo.serialize.jackson.JacksonSerialization
ObjectMapper:
默认情况下,Jackson序列化和反序列化时所使用的ObjectMapper定义如下:
@Override
public ObjectMapper getObjectMapper()
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// objectMapper.disable(SerializationFeature.FLUSH_AFTER_WRITE_VALUE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.setTimeZone(TimeZone.getDefault());
return objectMapper;
使用
provider
XML
<dubbo:protocol name="dubbo" port="20880" serialization="jackson" />
配置文件
Properties
dubbo.protocols.id=jackson
dubbo.protocols.name=dubbo
dubbo.protocols.port=20880
dubbo.protocols.serialization=jackson
YAML
dubbo:
config:
multiple: true
protocols:
dubbo:
id: dubbo
name: dubbo
port: -1
jackson:
id: jackson
name: dubbo
port: 20880
serialization: jackson
consumer
无需其他配置
常见问题
- 不支持泛型对象的序列化, 如 List,Map类型的序列化和反序列化
参考文章
以上是关于Dubbo——Dubbo协议整合Jackson序列化解决方案的主要内容,如果未能解决你的问题,请参考以下文章