You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring测试中不修改ObjectMapper配置,如何将响应Integer转为Long?

解决ObjectMapper反序列化Long为Integer后的类型转换问题

这问题我之前踩过坑!ObjectMapper默认会把能塞进Integer的数值自动转成Integer类型,导致你后续强转Long时直接炸ClassCastException,不想改全局映射器配置的话,给你几个直接转换的靠谱方案:

方案1:指定精确的反序列化类型(最推荐)

根本不用先转成无泛型的Set再手动转换,直接告诉ObjectMapper你要的是Set<Long>类型,用TypeReference来明确泛型:

Set<Long> responseBody = objectMapper.readValue(
    result.getContentAsByteArray(),
    new TypeReference<Set<Long>>() {}
);
// 直接就能和otherSet比较,不用后续map转换了
assertThat(responseBody.equals(otherSet), is(true));

这样ObjectMapper会直接把JSON数组里的数值转成Long,从根源上避免类型不匹配的问题。

方案2:安全的类型判断转换

如果因为某些原因必须先读成Set<?>,那转换的时候别直接强转,先判断元素类型再处理:

Set<?> rawResponseBody = objectMapper.readValue(result.getContentAsByteArray(), Set.class);
Set<Long> responseBody = rawResponseBody.stream()
    .map(number -> {
        if (number instanceof Integer) {
            return ((Integer) number).longValue();
        } else if (number instanceof Long) {
            return (Long) number;
        }
        // 可以根据需求处理其他数字类型,比如BigInteger,或者抛异常提示
        throw new IllegalArgumentException("不支持的数字类型: " + number.getClass().getName());
    })
    .collect(Collectors.toSet());

assertThat(responseBody.equals(otherSet), is(true));

这种方式能兼容Integer和Long两种类型的元素,不会出现强转异常。

方案3:通用的字符串转Long(简单粗暴)

不管元素是Integer还是Long,先转成字符串再转成Long,适合大多数场景:

Set<?> rawResponseBody = objectMapper.readValue(result.getContentAsByteArray(), Set.class);
Set<Long> responseBody = rawResponseBody.stream()
    .map(number -> Long.valueOf(number.toString()))
    .collect(Collectors.toSet());

assertThat(responseBody.equals(otherSet), is(true));

这个方法不用判断类型,只要元素是数字类型(能正确转成字符串的数字)都能处理,缺点是如果有非数字类型的元素会报错,不过你的场景里应该都是数值,所以没问题。


内容的提问来源于stack exchange,提问作者JeyJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:37:40