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依赖:
- 移除原JSONB依赖:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive-jsonb</artifactId> </dependency>
- 添加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
相关产品推荐
相关产品推荐

