【java8】如何为泛型类自定义jackson反序列化器JsonDeserializer

缘起:如何避免在Jackson的反序列化语句中显式使用new TypeReference语句

在Jackson对字符串的反序列化测试中,发现传入的参数new TypeReference<Map<String, Integer>>() {} 使得反序列化得到的map泛型的到了保障

        JsonMap<Object> dummy = JsonUtils.createJsonMap(Collections.singletonMap("0", "1"));
        String s = dummy.toJSONString();
        Map<String, Integer> integerMap = mapper.readValue(s, new TypeReference<Map<String, Integer>>() {
   
        });
        // 这里输出的integerMap 是 {"0":1}而不是{"0":"1"}

不难发现,上面这个式子将“1”解析为1,也就是说泛型限制起了作用,jackson底层在反序列化时接受到了在new TypeReference过程中传递的信息。

但是这个过程我们总是要new一个匿名类出来,这无疑增加了许多的代码工作量,于是有了这样的尝试:

    public static <T> JsonMap<T> createJsonMap(String jsonStr) throws JsonProcessingException {
   
        return createJsonMap(mapper.readValue(jsonStr, new TypeReference<Map<String, T>>() {
   
        }));
    }

    public static <T> JsonMap<T> createJsonMap(String jsonStr, Class<T> tClass) throws JsonProcessingException {
   
        return createJsonMap(mapper.readValue(jsonStr, new TypeReference<Map<String, T>>() {
   
        }));
    }

不论是试图通过返回值来传T的信息,还是试图通过传Class<T>来传递信息,最终这两个实现里T都会当Object使用,泛型信息在方法内部丢失,这是擦除导致的。

jackson的 objectmapper的readValue这个方法里头根本得不到泛型限制信息。同样的问题也存在于自定义序列化器的过程中:

package com.fidt.fate.utils;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.IOException;

public class JsonMapDeserializer<T> extends JsonDeserializer<JsonMap<T>> {
   
    public static final JsonMapDeserializer INSTANCE = new JsonMapDeserializer();

    public JsonMapDeserializer() {
   
    }
    @Override
    public <T> JsonMap<T> deserialize(JsonParser jsonParser, 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值