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

如何自定义Spring Boot Validation的HTTP响应格式?

自定义Spring Boot Validation的异常响应格式

问题场景

项目中使用Spring Boot Validation做参数校验,相关配置及现象如下:

Gradle依赖配置

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

请求实体代码

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ApiTransactionRequest {
    private String id;
    @NotNull
    private String transaction_id;
    @NotNull
    private String apiOperation;
    @NotNull
    // 其他字段...
}

异常日志及默认响应

测试时日志抛出参数校验异常:

WARN 28840 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity

默认返回的HTTP响应格式:

{
   "timestamp": "2022-12-05T09:58:55.011+00:00",
   "status": 400,
   "error": "Bad Request",
   "path": "/transactions"
}

期望替换为自定义响应格式:

{
   "date": "2022-12-05",
   "status": 400.03,
   "error": "Transaction id is invalid",
   "message": "Transaction id is not null"
}

解决方法

1. 定义自定义响应实体类

创建与目标格式匹配的实体类,用于封装自定义响应数据:

import java.time.LocalDate;

public class CustomValidationErrorResponse {
    private LocalDate date;
    private double status;
    private String error;
    private String message;

    // Getter、Setter方法
    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public double getStatus() {
        return status;
    }

    public void setStatus(double status) {
        this.status = status;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

(若项目已引入Lombok,可直接用@Data注解替代手动编写Getter/Setter)

2. 实现全局异常处理器

通过@RestControllerAdvice和@ExceptionHandler捕获参数校验异常,转换为自定义响应:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.time.LocalDate;

@RestControllerAdvice
public class GlobalValidationExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<CustomValidationErrorResponse> handleValidationExceptions(MethodArgumentNotValidException ex) {
        CustomValidationErrorResponse response = new CustomValidationErrorResponse();
        // 获取首个校验失败的字段信息(如需处理多字段,可遍历getFieldErrors()集合)
        FieldError fieldError = ex.getBindingResult().getFieldErrors().get(0);
        String fieldName = fieldError.getField();
        
        // 组装自定义响应内容
        response.setDate(LocalDate.now());
        response.setStatus(400.03); // 自定义业务细分状态码
        response.setError(fieldName.replace("_", " ") + " is invalid");
        response.setMessage(fieldName.replace("_", " ") + " is not null");
        
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
}

3. 扩展说明

  • 若需返回多字段校验错误,可将CustomValidationErrorResponse中的error和message改为集合类型,遍历ex.getBindingResult().getFieldErrors()收集所有错误信息。
  • 字段名中的下划线替换为空格是为了匹配示例格式,可根据实际业务需求调整字符串处理逻辑。
  • 自定义的400.03为业务细分状态码,HTTP响应的状态码仍保持400,符合HTTP协议规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:40:19