首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有任何方法可以使用BigDecimal键将地图序列化为BigDecimal,而不是使用杰克逊作为字符串?

是否有任何方法可以使用BigDecimal键将地图序列化为BigDecimal,而不是使用杰克逊作为字符串?
EN

Stack Overflow用户
提问于 2021-07-09 08:17:22
回答 1查看 911关注 0票数 1

当尝试使用Map时,键被序列化为字符串,而值被正确地序列化为BigDecimal。这会在反序列化它时引起问题,因为它被反序列化为Map。

我需要将密钥序列化为BigDecimal而不是字符串,有什么方法可以做到吗?我正在使用Jackson-all-1.9.11.jar,但我也尝试使用jackson-2.12.4罐子,但同样的出现。

有什么解决办法吗?或者,我是否可以创建一个自定义序列化程序,它只覆盖ObjectMapper在BigDecimal键情况下自动使用的映射序列化程序?如果是,如何才能做到这一点?

下面是一个代码示例,包含返回的结果。

代码语言:javascript
复制
public static void main(String[] args)
{
   try
   {
      ObjectMapper mapper = new ObjectMapper();
      mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
      Map<BigDecimal, BigDecimal> map = new HashMap<>();
      map.put(BigDecimal.ONE, BigDecimal.ONE);
      map.put(BigDecimal.TEN, BigDecimal.TEN);
      String str = mapper.writeValueAsString(map);
      System.out.println(str);
  }
  catch(Exception e)
  {
      e.printStackTrace();
  }
}

结果如下:

代码语言:javascript
复制
["java.util.HashMap",{"10":["java.math.BigDecimal",10],"1":["java.math.BigDecimal",1]}]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-13 10:26:02

您需要为希望在Map中用作键的每个类实现一组自定义密钥序列化器和反序列化器。例如,对于数字,它可能如下所示:

代码语言:javascript
复制
class KeyBigDecimalJsonSerializer extends JsonSerializer<Number> {

    @Override
    public void serialize(Number value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeFieldName(value + "_" + value.getClass().getName());
    }
}

class CustomKeyDeserializer extends KeyDeserializer {

    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
        if (key.contains("_")) {
            return deserializeKeyWithClass(key, ctxt);
        }
        return key;
    }

    private Object deserializeKeyWithClass(String key, DeserializationContext ctxt) throws IOException {
        String[] parts = key.split("_");
        try {
            Class<?> aClass = ctxt.findClass(parts[1]);
            return mapper.readValue(parts[0], aClass);
        } catch (ClassNotFoundException e) {
            throw new IOException(e);
        }
    }
}

用法:

代码语言:javascript
复制
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class MapKeysApp {

    public static void main(String[] args) throws Exception {
        SimpleModule module = new SimpleModule();
        module.addKeySerializer(Number.class, new KeyBigDecimalJsonSerializer());
        module.addKeyDeserializer(Object.class, new CustomKeyDeserializer());

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        Map<Object, Object> map = new HashMap<>();
        map.put(BigDecimal.ONE, BigDecimal.ONE);
        map.put(BigDecimal.TEN, BigDecimal.TEN);
        map.put(2.1D, 2.1D);
        map.put(100, 100);
        map.put("TEN", "ten");

        String json = mapper.writeValueAsString(map);
        System.out.println(json);
        mapper.readValue(json, Map.class).forEach((k, v) -> {
            System.out.println(k + " (" + k.getClass().getName() + ") : " + v + " (" + v.getClass().getName() + ")");
        });
    }
}

以上代码打印:

代码语言:javascript
复制
["java.util.HashMap",{"100_java.lang.Integer":100,"10_java.math.BigDecimal":["java.math.BigDecimal",10],"TEN":"ten","2.1_java.lang.Double":2.1,"1_java.math.BigDecimal":["java.math.BigDecimal",1]}]
100 (java.lang.Integer) : 100 (java.lang.Integer)
10 (java.math.BigDecimal) : 10 (java.math.BigDecimal)
TEN (java.lang.String) : ten (java.lang.String)
2.1 (java.lang.Double) : 2.1 (java.lang.Double)
1 (java.math.BigDecimal) : 1 (java.math.BigDecimal)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68313450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档