Spring接口式投影DTO在RequestBody反序列化失败问题求助
接口式投影DTO是Spring Data专为查询场景设计的,它依赖动态代理生成实例,但Jackson处理@RequestBody时必须实例化具体类型,接口无法直接被实例化,这就是报错的核心原因。下面是几种可行的解决办法:
拆分职责,使用两个不同的DTO
单独定义一个接口用于查询投影(比如命名为ConditionProjection),再定义一个普通类用于Controller接收请求(比如ConditionRequest),类中添加无参构造、getter/setter,或者用Lombok的@Data简化代码。这种方案让查询和请求接收各司其职,字段有差异时也能灵活调整,是日常开发中最常用的做法。用Java Record替代接口
Java 16及以上版本的Record是不可变数据类,Spring Data JPA支持将其作为DTO投影使用,同时Jackson原生支持解析Record(因为Record自带全参构造和访问方法)。示例代码如下:public record ConditionDto(String temperature, String humidity) {}同一个Record既可以在Repository查询时获取投影结果,又能作为
@RequestBody的参数,实现双向复用。自定义Jackson反序列化器(不推荐)
给接口编写自定义反序列化器,手动实现实例化逻辑(比如创建接口的匿名实现类实例),但这种做法繁琐且无必要,除非有特殊场景需求,否则不建议采用。
至于是否需要转成类实现的DTO:不是必须,但如果项目使用Java 16以下版本,或者需要更灵活的字段处理(比如可变字段、默认值),转成普通类是非常稳妥的选择。若使用Java 16+,Record则是更简洁的替代方案。
内容的提问来源于stack exchange,提问作者Lecram

