验证与springframework的验证错误的枚举

问题描述 投票:0回答:3

TL; DR:枚举反序列化错误不是由org.springframework.validation.Errors在休息控制器抓

For reference: we didn't find a clean solution yet as we finally decided that no one should call us wit a bad enum


我有一个使用org.springframework.validation.Errors进行参数验证休息控制器:

@RequestMapping(value = "/vol1/frodo")
public ResponseEntity<Object> simpleMethodUsingPost(
        HttpServletRequest httpServletRequest,
        @Valid @RequestBody MySimpleObject simpleObject,
        Errors errors) {

    /* If an error occured, I need to log the object */
    if (errors.hasErrors()) {
        List<FieldError> fields = errors.getFieldErrors();
        doSomething(fields , simpleObject);
    }
}

我班MySimpleObject看起来是这样的:

public class MySimpleObject {
    @Valid
    @NotNull(message = "anObjectField is a mandatory field")
    private EmbeddedObject anObjectField = null;

    @Valid
    @NotNull(message = "aStringField is a mandatory field")
    private String aStringField = null;

    @Valid
    private MySimpleEnum aSimpleEnum = null;
}

而我的枚举类MySimpleEnum基本上是有两个值类:

public enum MySimpleEnum{

  ORC("ORC"),
  URUK("URUK");

  private String value;

  MySimpleEnum(String value) {
    this.value = value;
  }

  @Override
  public String toString() {
    return String.valueOf(value);
  }
}

这个对象(和错误的springframework的Error对象注入)的验证效果很好,当它在一个StringObject,但它会失败的enum的验证(因此包含有效-annoted枚举对象将失败过) 。

当试图在JSON String强制转换为枚举当值无效失败:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: 
Cannot deserialize value of type 'lotr.middleearth.model.MySimpleEnum' from String "HOBBIT"

如果我使用一个ResponseEntityExceptionHandler并覆盖handleHttpMessageNotReadable被抓住了这个反序列化的错误,但我没有访问到不同的其他参数,并且不能使用它们。

我如何可以配置一个验证,枚举或springframework的错误,这样此异常被捕获并可用在我的控制器的身体吗?

java spring error-handling enums exception-handling
3个回答
0
投票

所发生的问题是,在枚举MySimpleEnum没有恒定“矮人”的可能性是“ORC”和“乌鲁克”,在确认问题可以简单地用作例如:

@NotNull(message = "Custom message")
private MySimpleEnum aSimpleEnum

0
投票

最后我做类似的东西来提取要求有问题的领域:

int start = ex.getMessage().indexOf("[\"");
int end = ex.getMessage().indexOf("\"]");
String fieldName = exception.getMessage().substring(start + 2, end)

领域恰好是在括号之间的消息的结束。

我不是很骄傲之一,它的混乱,但它似乎是枚举的唯一途径。

我想这将是更好的使用字符串和正确的Spring确认,而不是,因为它依赖于实现太多,可能与未来的更新打破。


0
投票

我刚刚遇到了同样的问题,但不喜欢的为用户提供一个未格式化的“丑陋”的验证错误消息的想法。

首先,我做了枚举属性的POJO不能为空。

@NotNull(message = "Type must be NEW_APPLICATION or RENEWAL")
private RegistrationSubmissionTypeEnum type;

后来我换了二传,基本检查输入(作为一个字符串),看看它是否匹配的枚举之一。如果没有,我什么都不做,财产保持为空,它的报道早在验证错误消息(使用在@NotNull注释使用的消息文本)中的一个。

public void setType(Object typeInput) {
    for (RegistrationSubmissionTypeEnum typeEnum : RegistrationSubmissionTypeEnum.values()) {
        if (typeEnum.getKey().equalsIgnoreCase(typeInput.toString())) {
            this.type=RegistrationSubmissionTypeEnum.valueOf(typeInput.toString());
        }
    }
}

这是真正的关键。正常的行为,我们都鄙视产生难看的错误消息,但它也确实它在某种程度上使得单独显示此错误消息。就个人而言,我喜欢发回的所有错误集体。

我不上@NotNull消息硬编码的枚举值的风扇,但在此特定情况下(少数枚举值),这是优选的默认序列化枚举的错误消息,和一次性分离的错误的行为信息。

我认为是一个自定义的验证,但开始觉得沉重。也许有人可以改善这一点。

© www.soinside.com 2019 - 2024. All rights reserved.