@有效 |响应非常冗长,如何自定义?

@Valid | response very verbose, how to customize?

我有一个 Spring 启动微服务,我想验证端点的传入 requestBody。

通过将 @Valid@NotBlank 结合使用,我注意到答案非常冗长,而且我自定义的错误消息深入到对象中;这是一个例子:

{
    "timestamp": "2020-12-17T09:28:26.529+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "NotBlank.createUserRequest.username",
                "NotBlank.username",
                "NotBlank.java.lang.String",
                "NotBlank"
            ],
            "arguments": [
                {
                    "codes": [
                        "createUserRequest.username",
                        "username"
                    ],
                    "arguments": null,
                    "defaultMessage": "username",
                    "code": "username"
                }
            ],
            "defaultMessage": "USERNAME IS REQUIRED",
            "objectName": "createUserRequest",
            "field": "username",
            "rejectedValue": "",
            "bindingFailure": false,
            "code": "NotBlank"
        }
    ],
    "message": "Validation failed for object='createUserRequest'. Error count: 1",
    "path": "/api/user/create"
}

如何自定义返回的这个对象?我希望回复只是这样:

{
    "timestamp": "2020-12-17T09:28:26.529+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "USERNAME IS REQUIRED"
}

这是我的代码:

请求

@Data
public class CreateUserRequest {

@NotBlank(message = "username is required")
private String username;

@Size(min = 3, max = 64)
@NotBlank(message = "password is required")
private String password;

@NotBlank(message = "confirmPassword is required")
@Size(min = 3, max = 64)
private String confirmPassword;
}

控制器

@PostMapping("/create")
public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) {
    User user = appService.createUserAndCart(request);
    return ResponseEntity.ok(user);
}

感谢您的体验

你可以使用@ControllerAdvice/@RestControllerAdvice

它允许您处理整个应用程序中的异常。你可以把它看作是一个拦截器,拦截由 @RequestMapping 和类似注释的方法抛出的异常。

并添加这样的方法,

@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleException(Exception ex)
  //your custom body   
  return new ResponseEntity<>(body, HttpStatus.XXXXX);
}

您可以指定特定的异常类型(我认为您的情况是 InvalidArgumentException)

定义一个returnclass

import org.springframework.http.HttpStatus;

import java.util.HashMap;

/**
 * @description:
 * @author: 582895699@qq.com
 * @time: 2020/12/20 下午 01:50
 */
public class Resp extends HashMap {
    private static final long serialVersionUID = 1L;

    public static final String TIMESTAMP = "timestamp";
    public static final String STATUS = "status";
    public static final String ERROR = "error";
    public static final String MESSAGE = "message";

    public static Resp fail(String message) {
        Resp resp = new Resp();
        resp.put(TIMESTAMP, System.currentTimeMillis());
        resp.put(STATUS, HttpStatus.BAD_REQUEST.value());
        resp.put(ERROR, HttpStatus.BAD_REQUEST.getReasonPhrase());
        resp.put(MESSAGE, message);
        return resp;
    }

    @Override
    public Object put(Object key, Object value) {
        return super.put(key, value);
    }
}

定义全局异常处理class并获取异常信息

import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @description:
 * @author: 582895699@qq.com
 * @time: 2020/12/20 下午 01:55
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Resp methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().get(0);
        String message = objectError.getDefaultMessage();
        return Resp.fail(message);
    }
}