@有效 |响应非常冗长,如何自定义?
@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);
}
}
我有一个 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);
}
}