Spring 验证失败时枚举字段上的自定义错误消息

Pet*_*ski 7 java rest enums spring spring-boot

我的 Spring DTO 中有一个枚举字段,我在@RestController. 我希望在验证此枚举字段失败时创建自定义错误消息:

public class ConversionInputDto {

    // validation annotations
    private BigDecimal sourceAmount;

    // enum field
    @NotNull(message = ERROR_EMPTY_VALUE)
    private CurrencyFormat targetCurrency;

    // no-args constructor and getters
} 
Run Code Online (Sandbox Code Playgroud)

在我的情况下,以字符串形式接收输入并进行自定义注释似乎是一种矫枉过正,而我知道的另一种选择是InvalidFormatException通过捕获所有错误@ControllerAdvise并为它们返回相同的错误(因此,用户提交例如数字属性的字符串输入将得到相同的错误消息):

@ExceptionHandler(InvalidFormatException.class)
public void handleInvalidEnumAndAllOtherInvalidConversions(HttpServletResponse response) throws IOException {
    response.sendError(HttpStatus.BAD_REQUEST.value(), ERROR_MESSAGE);
}
Run Code Online (Sandbox Code Playgroud)

当前的默认验证错误太长,我想让它更加用户友好,例如“无效的货币格式值。请选择......”

“无效的 JSON 输入:无法从 String \"test\" 反序列化类型值 com.foreignexchange.utilities.CurrencyFormat:不是 Enum 类接受的值之一:[AUD、PLN、MXN、USD、CAD];嵌套异常为 com.fasterxml.jackson.databind .exc.InvalidFormatException:无法com.foreignexchange.utilities.CurrencyFormat从字符串“test”反序列化类型值 :不是 Enum 类接受的值之一:[AUD、PLN、MXN、USD、CAD]\n,位于 [来源:(PushbackInputStream); 行: 3, 列: 20] (通过参考链: com.foreignexchange.models.ConversionInputDto[\"targetCurrency\"])",

有没有一种优雅的方法来解决这个问题?也许在@ExceptionHandler检查哪个字段验证失败时需要一些额外的逻辑?

Pet*_*ski 5

感谢这些评论,我找到了一个解决方案,通过使用isAssignableFrom()为失败的枚举验证提供自定义错误消息:

@ExceptionHandler(InvalidFormatException.class)
public void handleOfflineBankApi(HttpServletResponse response, InvalidFormatException ex) throws IOException {
    if (ex.getTargetType().isAssignableFrom(CurrencyFormat.class)) {
        response.sendError(HttpStatus.BAD_REQUEST.value(), Constants.ERROR_INVALID_CURRENCY_FORMAT);
    } else {
        response.sendError(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)