Spring 验证 returns 长错误消息,而不仅仅是自定义消息
Spring validation returns long error messages, not just the customized message
Spring 验证 returns 长错误消息而不是自定义一次。
这是dto中的一段代码。
public class RequestDto implements Serializable {
@NotNull(message="{id.required}")
private Long id;
}
在控制器中为输入添加了@Valid。
@RequestMapping(value = ApiPath.PATH, method = RequestMethod.POST, produces = { "application/xml",
"application/json" })
public @ResponseBody ResultDecorator saveRequest(
@Valid @RequestBody RequestDto msaDisabScreenRequestDto) throws Exception {
}
API return出现以下错误。
<message>Validation failed for argument at index 0 in method: public om.gov.moh.msa.framework.resolver.ResultDecorator om.controller.MaController.saveRequest(om..dto.RequestDto) throws java.lang.Exception, with 1 error(s): [Field error in object 'requestDto' on field 'id': rejected value [null]; codes [NotNull.requestDto.id,NotNull.id,NotNull.java.lang.Long,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [requestDto.id,id]; arguments []; default message [civilId]]; **default message [ID is required.]]** </message>
自定义消息出现在末尾。 (默认消息[需要ID。)
对全局异常使用控制器建议,我正在覆盖 handleMethodArgumentNotValid。我怎样才能return在这里只显示自定义消息?
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
/**
* Spring validation related exception
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
apiError.setMessage(ex.getMessage());
return buildResponseEntity(apiError);
}
}
您可以收到 default/custom 消息,例如 result.getFieldError("yourFieldName").getDefaultMessage()
您可以通过如下所示的控制器方法捕获错误消息
@RequestMapping(value = ApiPath.PATH, method = RequestMethod.POST, produces = { "application/xml", "application/json" })
public @ResponseBody ResultDecorator saveRequest(@Valid @RequestBody RequestDto msaDisabScreenRequestDto, BindingResult result) throws Exception {
if(result.hasErrors()){
String errorMessage = result.getFieldError("yourFieldName").getDefaultMessage();
}
}
或通过全局异常处理程序
已更新
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
/**
* Spring validation related exception
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
//New Code
BindingResult bindingResult = ex.getBindingResult();
String errorMessage = result.getFieldError("yourFieldName").getDefaultMessage();
//---------------
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
apiError.setMessage(errorMessage);
return buildResponseEntity(apiError);
}
}
谢谢阿夫里迪,
创建了一个字符串缓冲区并将所有错误消息添加到其中。
/**
* Spring validation related exception
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
final StringBuffer errors = new StringBuffer();
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
for (final FieldError error : ex.getBindingResult().getFieldErrors()) {
errors.append("\n");
errors.append(error.getField() + ": " + error.getDefaultMessage());
}
apiError.setMessage(errors.toString());
return buildResponseEntity(apiError);
}
正如 Afridi 在 @ControllerAdvice
中所说,也可以这样做:
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@SuppressWarnings("unchecked")
@ResponseBody
public Result methodArgumentNotValidExceptionHandler(HttpServletRequest req, HttpServletResponse response, MethodArgumentNotValidException e) throws IOException {
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
// todo return to your custom result
}
有两点:
- 异常 class 是
MethodArgumentNotValidException
- 第一个错误
getDefaultMessage()
可以在 Annotation
中获取您的自定义消息
在 WebFlux 中:
句柄 WebExchangeBindException
用于自定义 @Valid
的默认错误消息
@ControllerAdvice
public class ValidationHandler {
@ExceptionHandler(WebExchangeBindException.class)
public ResponseEntity<List<String>> handleException(WebExchangeBindException e) {
var errors = e.getBindingResult()
.getAllErrors()
.stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toList());
return ResponseEntity.badRequest().body(errors);
}
}
Spring 验证 returns 长错误消息而不是自定义一次。
这是dto中的一段代码。
public class RequestDto implements Serializable {
@NotNull(message="{id.required}")
private Long id;
}
在控制器中为输入添加了@Valid。
@RequestMapping(value = ApiPath.PATH, method = RequestMethod.POST, produces = { "application/xml",
"application/json" })
public @ResponseBody ResultDecorator saveRequest(
@Valid @RequestBody RequestDto msaDisabScreenRequestDto) throws Exception {
}
API return出现以下错误。
<message>Validation failed for argument at index 0 in method: public om.gov.moh.msa.framework.resolver.ResultDecorator om.controller.MaController.saveRequest(om..dto.RequestDto) throws java.lang.Exception, with 1 error(s): [Field error in object 'requestDto' on field 'id': rejected value [null]; codes [NotNull.requestDto.id,NotNull.id,NotNull.java.lang.Long,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [requestDto.id,id]; arguments []; default message [civilId]]; **default message [ID is required.]]** </message>
自定义消息出现在末尾。 (默认消息[需要ID。)
对全局异常使用控制器建议,我正在覆盖 handleMethodArgumentNotValid。我怎样才能return在这里只显示自定义消息?
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
/**
* Spring validation related exception
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
apiError.setMessage(ex.getMessage());
return buildResponseEntity(apiError);
}
}
您可以收到 default/custom 消息,例如 result.getFieldError("yourFieldName").getDefaultMessage()
您可以通过如下所示的控制器方法捕获错误消息
@RequestMapping(value = ApiPath.PATH, method = RequestMethod.POST, produces = { "application/xml", "application/json" })
public @ResponseBody ResultDecorator saveRequest(@Valid @RequestBody RequestDto msaDisabScreenRequestDto, BindingResult result) throws Exception {
if(result.hasErrors()){
String errorMessage = result.getFieldError("yourFieldName").getDefaultMessage();
}
}
或通过全局异常处理程序
已更新
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
/**
* Spring validation related exception
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
//New Code
BindingResult bindingResult = ex.getBindingResult();
String errorMessage = result.getFieldError("yourFieldName").getDefaultMessage();
//---------------
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
apiError.setMessage(errorMessage);
return buildResponseEntity(apiError);
}
}
谢谢阿夫里迪, 创建了一个字符串缓冲区并将所有错误消息添加到其中。
/**
* Spring validation related exception
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
final StringBuffer errors = new StringBuffer();
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
for (final FieldError error : ex.getBindingResult().getFieldErrors()) {
errors.append("\n");
errors.append(error.getField() + ": " + error.getDefaultMessage());
}
apiError.setMessage(errors.toString());
return buildResponseEntity(apiError);
}
正如 Afridi 在 @ControllerAdvice
中所说,也可以这样做:
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@SuppressWarnings("unchecked")
@ResponseBody
public Result methodArgumentNotValidExceptionHandler(HttpServletRequest req, HttpServletResponse response, MethodArgumentNotValidException e) throws IOException {
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
// todo return to your custom result
}
有两点:
- 异常 class 是
MethodArgumentNotValidException
- 第一个错误
getDefaultMessage()
可以在Annotation
中获取您的自定义消息
在 WebFlux 中:
句柄 WebExchangeBindException
用于自定义 @Valid
@ControllerAdvice
public class ValidationHandler {
@ExceptionHandler(WebExchangeBindException.class)
public ResponseEntity<List<String>> handleException(WebExchangeBindException e) {
var errors = e.getBindingResult()
.getAllErrors()
.stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toList());
return ResponseEntity.badRequest().body(errors);
}
}