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

Quarkus中如何将JSON整数数组反序列化为List<List<Integer>>

问题:如何让JSONB反序列化时将数字转为List<List<Integer>>而非BigDecimal?

代码片段

@ApplicationScoped
@Path("/sets")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class PartitionSet {
    
    @Path("/form")
    @POST
    public Response create(List<List<BigDecimal>> partitions){
        Map<String, Integer> obj = new HashMap<String, Integer>();
        obj.put("numPartitions", partitions.size());
        buildGraph(partitions);
        return Response.status(Status.OK).entity(obj).build();
    }
}

问题详情

这段代码能正常运行,但我想把create方法的参数改成List<List<Integer>>,不想用JSONB默认的BigDecimal类型。直接修改参数类型后,反序列化过程不会报错,但调用partitions.get(<下标>).get(<下标>)时会抛出如下异常:

java.lang.ClassCastException: class java.math.BigDecimal cannot be cast to class java.lang.Integer (java.math.BigDecimal and java.lang.Integer are in module java.base of loader 'bootstrap')

当前pom.xml中的依赖如下,是否需要更换依赖来实现需求?

<dependency> 
    <groupId>io.quarkus</groupId> 
    <artifactId>quarkus-resteasy-reactive-jsonb</artifactId> 
</dependency>

补充输入的JSON示例:

[
  [16, 15, 2, 1],
  [16, 14, 3, 1]
]

解决方法

方案1:不更换依赖,配置JSONB解析规则

JSONB默认会把所有JSON数字解析为BigDecimal(为了兼容浮点数场景),可以通过配置修改这一行为,让整数自动解析为Integer:

方法A:全局配置(通过application.properties)

在src/main/resources/application.properties中添加以下配置:

quarkus.jsonb.deserialization.use-big-decimal-for-floats=false
quarkus.jsonb.deserialization.integer-parsing-mode=integer
  • 第一行:关闭默认用BigDecimal处理所有数字的逻辑
  • 第二行:指定整数类型优先解析为Integer而非Long或BigDecimal

配置完成后,直接将方法参数改为List<List<Integer>>即可正常使用。

方法B:自定义Jsonb配置Bean

如果需要更精细的控制,可以编写自定义配置Bean覆盖默认规则:

import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import jakarta.json.bind.config.DeserializationConfig;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;

@Provider
@ApplicationScoped
public class JsonbConfigProvider implements ContextResolver<Jsonb> {
    @Override
    public Jsonb getContext(Class<?> type) {
        JsonbConfig config = new JsonbConfig()
                .withDeserializationConfig(DeserializationConfig.with()
                        .useBigDecimalForFloats(false)
                        .integerParsingMode(DeserializationConfig.IntegerParsingMode.INTEGER));
        return JsonbBuilder.create(config);
    }
}

这个Bean会替换默认的JSONB配置,同样能实现整数转Integer的效果。

方案2:换用Jackson依赖(可选)

如果更习惯使用Jackson,可以替换JSONB依赖:

  1. 移除原JSONB依赖:
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive-jsonb</artifactId>
</dependency>
  1. 添加Jackson依赖:
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>

Jackson默认会根据目标类型自动解析JSON整数为Integer,无需额外配置,直接修改方法参数为List<List<Integer>>即可正常运行。

关于异常中的模块信息

异常里提到的java.base是Java核心模块,BigDecimal和Integer都属于这个模块,这只是JVM类加载机制的说明,无需额外处理,解决反序列化类型不匹配的问题后,该异常会自动消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:54:53