2017-08-30 297 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" 
} 

讓我知道這是否解決您的問題。