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

Spring RESTController中Java Record反序列化报无唯一构造函数异常

问题解决方案

不需要编写自定义反序列化器,按以下步骤排查调整即可快速解决问题。

两个报错的核心原因:

  • 初始运行时uuid字段为null,核心是Controller方法参数未加@RequestBody注解,Spring未走Jackson JSON反序列化链路,而是用普通JavaBean参数解析逻辑处理请求,本身对Record兼容性差,也不会自动完成JSON字符串到UUID的类型转换。
  • 新增构造函数后报找不到唯一构造器,是因为Record存在两个参数列表不同的全参构造器,Spring无法判定哪个是反序列化时使用的主构造器。

方案1:最简实现(推荐)

  • 删掉你额外新增的String参数构造函数,保留最原始的Record定义即可:
public record Order(UUID uuid, List<OrderItem> items) {}
  • 给Controller方法的Order参数加上@RequestBody注解,明确告知Spring该参数从请求体JSON解析:
@PostMapping(value = "/allocations")
public Allocation allocate(@RequestBody Order order) throws Exception {
    return planningService.allocate(order);
}

如果使用的是Spring Boot 2.6及以上版本,以上两步修改后即可正常解析请求:框架默认已适配Java Record,且Jackson内置了String到UUID的自动反序列化规则,你提供的请求体可以直接转换为Order实例。
如果使用的是更低版本的Spring Boot,只要确保项目引入的Jackson版本不低于2.12,手动给ObjectMapper注册JDK8模块即可:

@Bean
public ObjectMapper customObjectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new Jdk8Module());
    return mapper;
}

方案2:需保留额外构造函数的场景

如果业务逻辑确实需要使用接收String类型uuid的构造函数,不需要删除该构造函数,只需在Record的主构造器上添加@JsonCreator注解,明确指定Jackson反序列化时使用的构造器即可:

public record Order(UUID uuid, List<OrderItem> items) {

    // 业务用自定义构造函数
    public Order(String uuid, List<OrderItem> items) {
        this(UUID.fromString(uuid), items);
    }

    // 标记JSON反序列化使用的主构造器
    @JsonCreator
    public Order {}
}

同样需要保证Controller参数上添加了@RequestBody注解,即可正常完成反序列化。

注意:不要为了基础类型转换给Record额外添加构造函数,只要走正确的JSON反序列化链路,Jackson默认支持UUID、Java 8时间类等常用类型的字符串自动转换,无需额外编写转换逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:57:23