Java Spring Boot如何返回我自己的验证约束错误消息
当我的请求出现问题时,我需要有自己的错误响应主体,并且我试图使用Java Spring Boot如何返回我自己的验证约束错误消息,java,validation,spring-boot,exception-handling,query-parameters,Java,Validation,Spring Boot,Exception Handling,Query Parameters,当我的请求出现问题时,我需要有自己的错误响应主体,并且我试图使用@NotEmpty约束消息属性返回错误消息 这是我的类,它使用我需要的正文返回错误消息: package c.m.nanicolina.exceptions; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MissingS
@NotEmpty
约束消息属性返回错误消息
这是我的类,它使用我需要的正文返回错误消息:
package c.m.nanicolina.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
@ControllerAdvice
public class CustomResponseEntityExceptionHandler {
@ExceptionHandler(value = {MissingServletRequestParameterException.class})
public ResponseEntity<ApiError> handleConflict(MissingServletRequestParameterException ex, WebRequest request) {
ApiError apiError = new ApiError(ex.getMessage(), ex.getMessage(), 1000);
return new ResponseEntity<ApiError>(apiError, null, HttpStatus.BAD_REQUEST);
}
}
在我的例外情况下,我无法找到获取该消息的方法Product.sku不能为空
并在我的错误响应中显示它。
我还检查了类
MissingServletRequestParameterException
,还有返回默认消息的方法getMessage
。您应该将其放在处理程序上
@ControllerAdvice
public class CustomResponseEntityExceptionHandler {
@ExceptionHandler(value = { MissingServletRequestParameterException.class })
public ResponseEntity<ApiError> handleConflict(MissingServletRequestParameterException ex, WebRequest request) {
String message = ex.getParameterName() + " cannot be empty";
ApiError apiError = new ApiError(ex.getMessage(), message, 1000);
return new ResponseEntity < ApiError > (apiError, null, HttpStatus.BAD_REQUEST);
}
}
是的,它是可行的&spring非常支持它。您只是缺少一些在spring中启用它的配置
- 使用Spring
注释启用Spring来验证控制器@Validated
- 在
中处理ControllerAdvice
,以捕获所有失败的验证消息ConstraintViolationException
- 在
中标记@RequestParam
,这样它就不会抛出MissingServletRequestParameterException,而是转到约束验证的下一步required=false
@ControllerAdvice
公共类CustomResponseEntityExceptionHandler{
@例外处理程序
公共响应属性句柄(ConstraintViolationException异常){
//您将得到所有javax失败的验证,可以是多个
//因此,您可以返回一组错误消息,也可以只返回第一条消息
String errorMessage=new ArrayList(exception.getConstraintViolations()).get(0.getMessage();
APIRROR APIRROR=新的APIRROR(errorMessage,errorMessage,1000);
返回新的ResponseEntity(apiError,null,HttpStatus.BAD_请求);
}
}
@RestController
@验证
公共类最小库存控制器{
@请求映射(value=“/minimumstock”)
公共产品(
@RequestParam(value=“product.sku”,required=false)@NotEmpty(message=“product.sku不能为空”)字符串sku,
@RequestParam(value=“stock.branch.id”,required=false)字符串branchID){
返回null;
}
}
注意:
MissingServletRequestParameterException
将无法访问javax验证消息,因为它是在请求生命周期中进行约束验证之前抛出的。是的,这是可能的。这样做:
@ExceptionHandler(MethodArgumentNotValidException.class)
公共响应处理方法无效(MethodArgumentNotValidException ex){
ServiceException=ServiceException.wrap(例如,ErrorCode.FIELD\u验证);
BindingResult=ex.getBindingResult();
for(FieldError e:results.getFieldErrors()){
exception.addLog(e.getDefaultMessage(),e.getField());
}
//在日志中记录详细信息
错误(“无效参数异常:{}”,异常.logWithDetails(),异常);
返回ResponseEntity.status(exception.getErrorCode().getHttpStatus())
.body(ArgumentsErrorResponseDTO.builder()
.code(异常.getErrorCode().getCode())
.message(异常.getMessage())
.details(exception.getProperties())
.build());
}
如果这有帮助,我在这里找到了解决此问题的方法:
必须将此方法添加到CustomResponseEntityExceptionHandler类:
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
List<String> details = new ArrayList<>();
for(ObjectError error : ex.getBindingResult().getAllErrors()) {
details.add(error.getDefaultMessage());
}
ErrorMessage error = new ErrorMessage(new Date(), details.toString());
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
@覆盖
受保护的ResponseEntity handleMethodArgumentNotValid无效(MethodArgumentNotValidException ex、HttpHeaders标头、HttpStatus状态、WebRequest请求){
列表详细信息=新建ArrayList();
对于(ObjectError错误:例如getBindingResult().getAllErrors()){
add(error.getDefaultMessage());
}
ErrorMessage error=新的ErrorMessage(new Date(),details.toString());
返回新的ResponseEntity(错误,HttpStatus.BAD_请求);
}
但是有什么方法可以让我从控制器中的@NotEmpty
注释中获取消息吗?@Gerep我不知道你是否能做到,但我已经用一种解决方法更新了我的答案。希望这有帮助。
@RequestMapping(value = "/minimumstock")
public Product product(@RequestParam(required = false) String sku, @RequestParam(value = "stock.branch.id") String branchID) {
if (StringUtils.isEmpty(sku))
throw YourException("Product.sku cannot be empty");
return null;
}
@ControllerAdvice
public class CustomResponseEntityExceptionHandler {
@ExceptionHandler
public ResponseEntity<ApiError> handle(ConstraintViolationException exception) {
//you will get all javax failed validation, can be more than one
//so you can return the set of error messages or just the first message
String errorMessage = new ArrayList<>(exception.getConstraintViolations()).get(0).getMessage();
ApiError apiError = new ApiError(errorMessage, errorMessage, 1000);
return new ResponseEntity<ApiError>(apiError, null, HttpStatus.BAD_REQUEST);
}
}
@RestController
@Validated
public class MinimumStockController {
@RequestMapping(value = "/minimumstock")
public Product product(
@RequestParam(value = "product.sku", required=false) @NotEmpty(message = "Product.sku cannot be empty") String sku,
@RequestParam(value = "stock.branch.id", required=false) String branchID) {
return null;
}
}
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
List<String> details = new ArrayList<>();
for(ObjectError error : ex.getBindingResult().getAllErrors()) {
details.add(error.getDefaultMessage());
}
ErrorMessage error = new ErrorMessage(new Date(), details.toString());
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}