うちは オビト956 2025-09-27 16:45 采纳率: 50%
浏览 7

使用 @Validated 进行校验 @RequestBody 无法将 json 数据转化为对象

问题:使用 @Validated 进行校验 @RequestBody 无法将 json 数据转化为对象

代码:
接口

    @PostMapping("/add")
    public BaseResponse<Long> addInterface(@Validated @RequestBody InterfaceInfoAddRequest interfaceInfoAddRequest, HttpServletRequest request) {
        Long newInterfaceId = interfaceInfoService.addInterface(interfaceInfoAddRequest, request);
        return ResultUtils.success(newInterfaceId);
    }

InterfaceInfoAddRequest :

@Data
public class InterfaceInfoAddRequest implements Serializable {

    /**
     * 名称
     */
    @NotNull
    @NotBlank
    @Length(max = 20)
    private String name;

    private String description;
    private String url;
    private String requestHeader;
    private String responseHeader;
    private String method;

    private String requestParam;
    private static final long serialVersionUID = 1L;
}

前端传入数据:

img

后端报错:

img

但是如果在 InterfaceInfoAddRequest 中不使用 validation 的校验注解的话又可以正常解析:
修改后:
InterfaceInfoAddRequest :

@Data
public class InterfaceInfoAddRequest implements Serializable {

    /**
     * 名称
     */
    private String name;

    private String description;
    private String url;
    private String requestHeader;
    private String responseHeader;
    private String method;

    private String requestParam;
    private static final long serialVersionUID = 1L;
}

运行成功:

img

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-09-27 16:52
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你遇到的问题是:使用 @Validated 注解对 @RequestBody 进行校验时,无法将 JSON 数据正确地转换为 Java 对象(即 InterfaceInfoAddRequest。而如果去掉校验注解(如 @NotNull, @NotBlank, @Length),则可以正常解析。


    ✅ 问题原因分析

    1. @Validated@RequestBody 的配合问题
      Spring Boot 中,@Validated 是用于方法参数级别的校验,通常用于 @RequestParam@PathVariable@RequestBody 参数。但需要注意的是,当使用 @RequestBody 时,Spring 会尝试将请求体反序列化为对象,这个过程和校验是两个独立的步骤

    2. 可能的原因:

      • JSON 字段与 Java 属性不匹配:例如字段名大小写不一致(如 name vs Name)、缺少 getter/setter 方法等。
      • 未启用校验支持:需要确保在启动类或配置中启用了校验功能。
      • 依赖缺失:如果项目中没有引入 spring-boot-starter-validation,那么校验注解(如 @NotBlank, @Length)不会生效,可能导致反序列化失败。

    🔧 解决方案

    1. 确保已添加 spring-boot-starter-validation 依赖

    如果你使用的是 Maven,确保 pom.xml 中包含以下依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    

    如果是 Gradle,则添加:

    implementation 'org.springframework.boot:spring-boot-starter-validation'
    

    2. 检查 JSON 字段与 Java 类属性是否匹配

    确保前端传入的 JSON 字段与 InterfaceInfoAddRequest 类中的字段名称完全一致(包括大小写)。例如:

    前端传入的 JSON 示例:

    {
      "name": "接口名称",
      "description": "描述",
      "url": "http://example.com",
      "requestHeader": "{ \"Content-Type\": \"application/json\" }",
      "responseHeader": "{ \"Content-Type\": \"application/json\" }",
      "method": "POST",
      "requestParam": "{ \"key\": \"value\" }"
    }
    

    Java 类字段应为:

    private String name;
    private String description;
    private String url;
    private String requestHeader;
    private String responseHeader;
    private String method;
    private String requestParam;
    

    3. 确保 @Data 注解可用

    你已经使用了 @Data,这是 Lombok 提供的,确保你已正确引入 Lombok 依赖。例如:

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <scope>provided</scope>
    </dependency>
    

    4. 确保 @Validated 正确使用

    @Validated 一般用于方法参数上,而不是类级别。你现在的用法是正确的:

    @PostMapping("/add")
    public BaseResponse<Long> addInterface(
        @Validated @RequestBody InterfaceInfoAddRequest interfaceInfoAddRequest, 
        HttpServletRequest request
    ) {
        // ...
    }
    

    但是注意,@Validated 只能用于方法参数,并且要配合 @RequestBody 使用。


    5. 检查日志中的具体错误信息

    查看后端报错日志,是否有类似下面的信息:

    Failed to bind request body [xxx] to class com.example.InterfaceInfoAddRequest: 
    Invalid property 'xxx' of bean class [com.example.InterfaceInfoAddRequest]
    

    这说明 JSON 字段与 Java 属性不匹配,或者缺少 setter 方法。


    6. 使用 @JsonProperty 显式映射字段

    如果字段名不一致,可以使用 Jackson 的 @JsonProperty 注解进行映射:

    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonProperty;
    
    @Data
    public class InterfaceInfoAddRequest implements Serializable {
    
        @JsonProperty("name") // 如果前端传的是 "name",Java 是 "name",可以省略
        @NotNull
        @NotBlank
        @Length(max = 20)
        private String name;
    
        // 其他字段...
    }
    

    ✅ 最终建议

    • 确保依赖完整(spring-boot-starter-validation + lombok);
    • 检查 JSON 字段与 Java 属性是否匹配;
    • 查看日志,定位具体错误;
    • 如果仍然无法解决,可以提供完整的错误日志,我可以帮你进一步分析。

    📌 总结

    | 问题 | 原因 | 解决方案 | |------|------|----------| | 无法将 JSON 转换为对象 | JSON 字段与 Java 属性不匹配 | 检查字段名一致性 | | 校验注解导致反序列化失败 | 未启用校验支持或依赖缺失 | 添加 spring-boot-starter-validation | | 报错信息不明确 | 日志未显示具体错误 | 查看详细日志,定位字段不匹配 |


    如有需要,我可以提供一个完整的 InterfaceInfoAddRequest 示例代码以及对应的 Controller 示例。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月27日