如何正确序列化/反序列化Java对象[]?

如何正确序列化/反序列化Java对象[]?,java,json,serialization,protocol-buffers,rpc,Java,Json,Serialization,Protocol Buffers,Rpc,我正在编写一个rpc框架,但面临一个关于序列化的问题 您知道,要在客户端和服务器之间转换请求,我应该有这样一个请求类: class Request { // target service class private Class<?> targetService; // target service method private String targetMethod; // target method param types priva

我正在编写一个rpc框架,但面临一个关于序列化的问题

您知道,要在客户端和服务器之间转换请求,我应该有这样一个请求类:

class Request {
    // target service class
    private Class<?> targetService;
    // target service method
    private String targetMethod;
    // target method param types
    private Class<?>[] targetParamTypes;
    // the params
    private Object[] targetParams;
    // getters & setters & contructors
}
类请求{
//目标服务类别
私人类目标服务;
//目标服务方法
私有字符串targetMethod;
//目标方法参数类型
私有类[]targetParamTypes;
//情妇
私有对象[]targetParams;
//获取者、设置者和构建者
}
但是:

  • 对于
    targetParams
    字段,如果我使用Gson作为序列化工具,它将得到
    com.google.Gson.internal.LinkedTreeMap无法转换为.packages.to.MyClass
    错误,如果我将POJO放入
    targetParams
    ,以解决一般问题

  • 对于
    int
    类,Gson总是将其解析为
    Double
    ,因此我不能使用
    targetParamTypes[I].cast(targetParams[I])
    强制将其转换为整数(Double不能转换为整数),它会吸收

  • 有人有解决问题的办法吗?如何使序列化/反序列化步骤快速准确?或任何推荐的工具

    我试过:

    • 格森,先解决问题
    • Kyro,编解码器系统糟透了,我不知道如何序列化/反序列化HashMap
    • protostuff,嗯,它不支持Java9+,我的环境是Java11,糟透了
    有什么建议吗?

    你可以看看。Jackson的
    ObjectMapper
    应该能够将
    请求
    对象转换为
    字符串
    ,反之亦然

    编辑:添加示例

    请求实体:

    class Request {
    
        private Class<?> targetService;
        private String targetMethod;
        private Class<?>[] targetParamTypes;
        private Object[] targetParams;
    
        // needed by Jackson
        private Request(){
    
        }
    
        public Request(Class<?> targetService, 
                       String targetMethod, 
                       Class<?>[] targetParamTypes, 
                       Object[] targetParams) {
            this.targetService = targetService;
            this.targetMethod = targetMethod;
            this.targetParamTypes = targetParamTypes;
            this.targetParams = targetParams;
        }
    
        // getters and setters, needed by Jackson
    
    }
    
    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
    
        Request req = new Request(String.class, "test", new Class[] {String.class}, new Object[] {"Test"});
        String serialized = mapper.writeValueAsString(req);
        System.out.println(serialized);
    
        req = mapper.readValue(serialized, Request.class);
        System.out.println(req);
    }
    
    你可以看看。Jackson的
    ObjectMapper
    应该能够将
    请求
    对象转换为
    字符串
    ,反之亦然

    编辑:添加示例

    请求实体:

    class Request {
    
        private Class<?> targetService;
        private String targetMethod;
        private Class<?>[] targetParamTypes;
        private Object[] targetParams;
    
        // needed by Jackson
        private Request(){
    
        }
    
        public Request(Class<?> targetService, 
                       String targetMethod, 
                       Class<?>[] targetParamTypes, 
                       Object[] targetParams) {
            this.targetService = targetService;
            this.targetMethod = targetMethod;
            this.targetParamTypes = targetParamTypes;
            this.targetParams = targetParams;
        }
    
        // getters and setters, needed by Jackson
    
    }
    
    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
    
        Request req = new Request(String.class, "test", new Class[] {String.class}, new Object[] {"Test"});
        String serialized = mapper.writeValueAsString(req);
        System.out.println(serialized);
    
        req = mapper.readValue(serialized, Request.class);
        System.out.println(req);
    }
    

    使用JSON而不是GSON并在pojo中实现Serializable

    使用JSON而不是GSON并在pojo中实现Serializable

    它不是和实现Serializable类一样简单吗?它不是和实现Serializable类一样简单吗?不,不行,在线程“main”中使用Serializable[]时出错:
    异常com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造
    java.io.Serializable`。。。顺便说一句,您能否共享一段示例代码来序列化/反序列化请求类?@UkonnRa添加了示例。不要为
    targetParams
    重构到
    Serializable
    ,但要确保存储在那里的对象确实是可序列化的。哇,它工作了!太多了!但是为什么Gson不能使用类似的代码(使用toJson,fromJson)…欢迎。尽管方法签名在某种程度上是相似的,但Gson API使用不同的实现来序列化/反序列化对象。我没有用过Gson,所以我不知道它为什么会失败。不,它失败了。。。我发现类型是错误的:
    var obj=newrequestwrapper(UUID.randomuid().toString(),System.currentTimeMillis(),HelloWorldService.class,“getExp”,新类[]{MessageRequest.class},新对象[]{newmessagerequest(UUID.randomuid().toString(),2,10)})newObj.getParams()[0]
    将是一个
    java.util.LinkedHashMap
    而不是一个
    MessageRequest
    No not work,当我在线程“main”中使用Serializable[]时会出现错误:
    异常com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造
    java.io.Serializable`。。。顺便说一句,您能否共享一段示例代码来序列化/反序列化请求类?@UkonnRa添加了示例。不要为
    targetParams
    重构到
    Serializable
    ,但要确保存储在那里的对象确实是可序列化的。哇,它工作了!太多了!但是为什么Gson不能使用类似的代码(使用toJson,fromJson)…欢迎。尽管方法签名在某种程度上是相似的,但Gson API使用不同的实现来序列化/反序列化对象。我没有用过Gson,所以我不知道它为什么会失败。不,它失败了。。。我发现类型是错误的:
    var obj=newrequestwrapper(UUID.randomuid().toString(),System.currentTimeMillis(),HelloWorldService.class,“getExp”,新类[]{MessageRequest.class},新对象[]{newmessagerequest(UUID.randomuid().toString(),2,10)})newObj.getParams()[0]
    将是一个
    java.util.LinkedHashMap
    而不是一个
    MessageRequest