2017-08-30 293 views
0

的领域,我有以下@RestController@RequestBody @Valid SomeDTO有枚举类型,自定义错误消息

@RequestMapping(...) 
public ResponseEntity(@RequestBody @Valid SomeDTO, BindingResult errors) { 
//do something with errors if validation error occur 
} 

public class SomeDTO { 
    public SomeEnum someEnum; 
} 

如果JSON请求{ "someEnum": "valid value" },一切工作正常。但是,如果请求是{ "someEnum": "invalid value" },则它只返回错误代码400.

如何捕获此错误,以便我可以提供自定义错误消息,例如“someEnum必须为值A/B/C”。

+0

请检查https://www.javacodegeeks.com/2013/05/spring-from-the-trenches-adding-validation-to-a-rest-api.html,它显示了如何使用@ControllerAdvice –

+0

@ AmitKBist这不会回答关于枚举类型的问题 – timpham

回答

0

勇能实现这个使用@ControllerAdvice如下

@org.springframework.web.bind.annotation.ExceptionHandler(value = {InvalidFormatException.class}) 
    public ResponseEntity handleIllegalArgumentException(InvalidFormatException exception) { 

     return ResponseEntity.badRequest().body(exception.getMessage()); 
    } 

基本上,这个想法是捕捉com.fasterxml.jackson.databind.exc.InvalidFormatException和处理它按您的要求。

0
@ControllerAdvice 
public static class GenericExceptionHandlers extends ResponseEntityExceptionHandler { 

    @Override 
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException e, HttpHeaders headers, HttpStatus status, WebRequest request) { 
     return new ResponseEntity<>(new ErrorDTO().setError(e.getMessage()), HttpStatus.BAD_REQUEST); 
    } 
} 

我创建了一个测试功能齐全的春天启动的应用上Bitbucket

0

@Valid与Hibernate的豆验证的事情。目前不支持枚举类型。我发现这个答案是最接近的,https://funofprograming.wordpress.com/2016/09/29/java-enum-validator/,但是缺点是你必须改为使用String类型的枚举字段。

控制器代码,StackDTO中有一个枚举PaymentType:

@RequestMapping(value = "/reviews", method = RequestMethod.POST) 
    @ResponseBody 
    public ResponseEntity<String> add(@RequestBody StackDTO review) { 

     return new ResponseEntity<String>(HttpStatus.ACCEPTED); 
    } 

创建一个异常类

0

你不需要为@Valid枚举验证,可以使用下面的代码实现所需的响应作为EnumValidationException

public class EnumValidationException extends Exception { 

    private String enumValue = null; 
    private String enumName = null; 

    public String getEnumValue() { 
     return enumValue; 
    } 

    public void setEnumValue(String enumValue) { 
     this.enumValue = enumValue; 
    } 

    public String getEnumName() { 
     return enumName; 
    } 

    public void setEnumName(String enumName) { 
     this.enumName = enumName; 
    } 

    public EnumValidationException(String enumValue, String enumName) { 
     super(enumValue); 

     this.enumValue = enumValue; 
     this.enumName = enumName; 
    } 

    public EnumValidationException(String enumValue, String enumName, Throwable cause) { 
     super(enumValue, cause); 

     this.enumValue = enumValue; 
     this.enumName = enumName; 
    } 
} 

我有枚举如下,与上一个方法特别注明@JsonCreator创建

public enum PaymentType { 

    CREDIT("Credit"), DEBIT("Debit"); 

    private final String type; 

    PaymentType(String type) { 
     this.type = type; 
    } 

    String getType() { 
     return type; 
    } 

    @Override 
    public String toString() { 
     return type; 
    } 

    @JsonCreator 
    public static PaymentType create (String value) throws EnumValidationException { 
     if(value == null) { 
      throw new EnumValidationException(value, "PaymentType"); 
     } 
     for(PaymentType v : values()) { 
      if(value.equals(v.getType())) { 
       return v; 
      } 
     } 
     throw new EnumValidationException(value, "PaymentType"); 
    } 
} 

最后RestErrorHandler类,

@ControllerAdvice 
public class RestErrorHandler { 

    @ExceptionHandler(HttpMessageNotReadableException.class) 
    @ResponseStatus(HttpStatus.BAD_REQUEST) 
    @ResponseBody 
    public ResponseEntity<ValidationErrorDTO> processValidationIllegalError(HttpMessageNotReadableException ex, 
      HandlerMethod handlerMethod, WebRequest webRequest) { 

     EnumValidationException exception = (EnumValidationException) ex.getMostSpecificCause(); 

     ValidationErrorDTO errorDTO = new ValidationErrorDTO(); 
     errorDTO.setEnumName(exception.getEnumName()); 
     errorDTO.setEnumValue(exception.getEnumValue()); 
     errorDTO.setErrorMessage(exception.getEnumValue() + " is an invalid " + exception.getEnumName()); 
     return new ResponseEntity<ValidationErrorDTO>(errorDTO, HttpStatus.BAD_REQUEST); 
    } 

} 

ValidationErrorDTO与enumValue,enumName和的errorMessage的设置器/吸气剂的DTO。现在,当您发送POST呼叫控制器端点/评论下文要求

{"paymentType":"Credit2"} 

然后代码返回响应,400下方响应主体 -

{ 
    "enumValue": "Credit2", 
    "enumName": "PaymentType", 
    "errorMessage": "Credit2 is an invalid PaymentType" 
} 

让我知道这是否解决您的问题。