Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hutool-json toBean后的对象在dubbo3协议下传输序列化异常 #3477

Closed
gg159753 opened this issue Jan 25, 2024 · 7 comments
Closed
Labels

Comments

@gg159753
Copy link

版本情况

JDK版本: openjdk_8_201
hutool版本: 5.8.25(请确保最新尝试是否还有问题)

问题描述(包括截图)

使用JSONUtil.toBean(s1,class)直接作为dubbo接口的返回。
在返回对象中有一个Map<String, Object>参数。 对端收到的JSONObject变成了JSONObject的config和raw
是由于dubbo3后面的版本默认使用fastjson2作为序列化方案。
追了一下堆栈应该是fastjson2构造JSONObject时调用了无参构造器再塞值导致多了一层raw

想请问一下有没有什么解决方案。 或者JSONUtil.toBean(s1,class)有办法把未知对象不转成JSONObject而是Map吗

  1. 复现代码
package com.example.demo;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.leoao.kefu.base.Entry;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.serialize.fastjson2.*;
import org.apache.dubbo.common.utils.SerializeCheckStatus;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.protocol.injvm.DefaultParamDeepCopyUtil;

import java.io.*;
import java.util.*;

@Slf4j
public class DemoApplication {


    /**
     * 正常情况输出一个pageJson的对象
     * 实际输出是JSONObject的config和raw
     * @param args
     */
    public static void main(String[] args) {
        Fastjson2SecurityManager manager = FrameworkModel.defaultModel().getBeanFactory().getBean(Fastjson2SecurityManager.class);
        manager.notifyCheckSerializable(false);
        manager.notifyCheckStatus(SerializeCheckStatus.DISABLE);
        URL consumerUrl =
                URL.valueOf("dubbo://127.0.0.1:8104?prefer.serialization=fastjson2",FrameworkModel.defaultModel());
        BizDataDTO p = new BizDataDTO();
        Map<String,Object> m = new HashMap<>();
        m.put("title","123");
        m.put("hahah",new Entry().setValue("hahahah"));
        p.setOutputProps(m);
        String s1 = JSON.toJSONString(p);
        BizDataDTO pj = JSONUtil.toBean(s1,BizDataDTO.class);
        JSONObject j1 = (JSONObject)pj.getOutputProps().get("hahah");
        System.out.println(j1);
        BizDataDTO copy_p = new DefaultParamDeepCopyUtil().copy(consumerUrl, pj, BizDataDTO.class);
        JSONObject j2 = (JSONObject)copy_p.getOutputProps().get("hahah");
        System.out.println(j2);
    }

    @Data
    public static class BizDataDTO implements Serializable {
        private Map<String, Object> outputProps = new HashMap<>();
    }

}
org.apache.dubbo dubbo-spring-boot-starter 3.2.10 com.alibaba.fastjson2 fastjson2 com.alibaba.fastjson2 fastjson2 2.0.43 cn.hutool hutool-all 5.8.25
@gg159753
Copy link
Author

image

@looly
Copy link
Member

looly commented Jan 26, 2024

尝试使用JSONUtil.putDeserializer,自定义反序列化。

@looly looly closed this as completed Jan 26, 2024
@looly looly added the question label Jan 26, 2024
@gg159753
Copy link
Author

gg159753 commented Jan 26, 2024

尝试使用JSONUtil.putDeserializer,自定义反序列化。

追过链路并不行 cn.hutool.json.serialize.GlobalSerializeMapping#getDeserializer 内部缓存的key是type对象。 如果我自己put(new TypeReference<Map<String,Object>>(){},()->{}) ; key值的对象和反序列时候的targetType并不是一个对象。 导致取到的反序列化Deserializer为空。
感觉这里取Deserializer时应该把type转为string

@looly
Copy link
Member

looly commented Jan 26, 2024

@gg159753 我想你应该传Map.class,这样是处理所有Map。

@gg159753
Copy link
Author

image

key传Map.class 不行。 反序列化时候取的是type

@gg159753
Copy link
Author

Type type = (new TypeReference<Map<String, Object>>(){}).getType(); JSONUtil.putDeserializer(type, (JSONDeserializer<Map<String, Object>>) json -> { System.out.println("aaaaaaa"); return new HashMap(); });

这样可以了 不追代码真不知道。。。感觉取Deserializer时把type转为string 更好一点

@looly
Copy link
Member

looly commented Jan 26, 2024

@gg159753 这里确实比较繁琐,不过使用String貌似泛型稍有差异也会不匹配。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants