Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot SpringBoot rest验证不会因错误的枚举输入而失败_Spring Boot_Rest_Validation_Enums - Fatal编程技术网

Spring boot SpringBoot rest验证不会因错误的枚举输入而失败

Spring boot SpringBoot rest验证不会因错误的枚举输入而失败,spring-boot,rest,validation,enums,Spring Boot,Rest,Validation,Enums,我有一个SpringBoot rest POST端点,在主体中我发布了一个枚举值。此调用不会因输入错误的值而失败。我希望rest调用失败,而不是为无法反序列化的值返回null 我已经尝试了以下自定义ObjectMapper配置,但我作为enum放入的任何错误输入都会反序列化为null @Bean @Primary public ObjectMapper customJsonObjectMapper() { Jackson2ObjectMapperBuilder builder = new

我有一个SpringBoot rest POST端点,在主体中我发布了一个枚举值。此调用不会因输入错误的值而失败。我希望rest调用失败,而不是为无法反序列化的值返回null

我已经尝试了以下自定义ObjectMapper配置,但我作为enum放入的任何错误输入都会反序列化为null

@Bean
@Primary
public ObjectMapper customJsonObjectMapper() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    ObjectMapper objectMapper = builder.build();
    objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, false);
    SimpleModule module = new SimpleModule();
    objectMapper.registerModule(module);
    return objectMapper;
}
例如,如果我有枚举:

public enum CouponOddType {
  BACK("back"),
    LAY("lay");

  private String value;

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

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

  @JsonCreator
  public static CouponOddType fromValue(String text) {
    for (CouponOddType b : CouponOddType.values()) {
      if (String.valueOf(b.value).equals(text)) {
        return b;
      }
    }
    return null;
  }
}
请求映射到的dto:

    @ApiModel(description = "Filter used to query coupons. Filter properties are combined with AND operator")
@Validated
@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2020-07-07T13:12:58.487+02:00[Europe/Ljubljana]")
public class CouponQueryFilter   {
  
  @JsonProperty("statuses")
  @Valid
  private List<CouponStatus> statuses = null;

  @JsonProperty("oddTypes")
  @Valid
  private List<CouponOddType> oddTypes = null;

  public CouponQueryFilter statuses(List<CouponStatus> statuses) {
    this.statuses = statuses;
    return this;
  }

  public CouponQueryFilter addStatusesItem(CouponStatus statusesItem) {
    if (this.statuses == null) {
      this.statuses = new ArrayList<>();
    }
    this.statuses.add(statusesItem);
    return this;
  }

  /**
   * Get statuses
   * @return statuses
  **/
  @ApiModelProperty(value = "")
      @Valid
    public List<CouponStatus> getStatuses() {
    return statuses;
  }

  public void setStatuses(List<CouponStatus> statuses) {
    this.statuses = statuses;
  }

  public CouponQueryFilter oddTypes(List<CouponOddType> oddTypes) {
    this.oddTypes = oddTypes;
    return this;
  }

  public CouponQueryFilter addOddTypesItem(CouponOddType oddTypesItem) {
    if (this.oddTypes == null) {
      this.oddTypes = new ArrayList<>();
    }
    this.oddTypes.add(oddTypesItem);
    return this;
  }

  /**
   * Get oddTypes
   * @return oddTypes
  **/
  @ApiModelProperty(value = "")
      @Valid
    public List<CouponOddType> getOddTypes() {
    return oddTypes;
  }

  public void setOddTypes(List<CouponOddType> oddTypes) {
    this.oddTypes = oddTypes;
  }

}

我希望这种类型的请求会导致HTTP 404错误,而不是反序列化为null。

在这种情况下,Jackson的行为实际上与预期相符,并且反序列化逻辑中存在问题。最终,您希望错误的枚举值抛出错误并将该错误返回给用户。这实际上是spring和jackso的默认行为,将导致HTTP 400错误请求。在我看来,这是返回的适当错误(不是404),因为用户提供了错误的输入

除非有特定的原因让您在enum类中实现自定义的
@JsonCreator
,否则我将放弃它。这里发生的事情是,Jackson被告知使用此方法将字符串转换为枚举值,而不是使用defualt方法。当传递的文本不是枚举的有效值时,您将返回
null
,这将导致值反序列化为null

一个快速修复方法是删除
JsonCreator
,并允许jackson使用其默认行为来处理枚举。在大多数情况下,您添加的额外属性方法是不必要的

公共枚举耦合指定类型{ 背面(“背面”), (俗称"");; 私有字符串值; CoupOnAddType(字符串值){ 这个值=值; } } 如果出于其他原因需要保留创建者,则需要添加业务逻辑以确定数组中的
enum
值是否为null

private Response someSpringRestEndpoint(@RequestBody-CouponQueryFilter-filter){
if(filter.getOddTypes()!=null&&filter.getOddTypes()包含(null){
抛出新的CustomException()
}
if(filter.getStatuses()!=null&&filter.getStatuses()包含(null){
抛出新的CustomException()
}
//…其他业务逻辑
}

你能给出完整的例子吗?因为反序列化应该fail@user7294900我已经更新了这个问题,可能问题是枚举值是数组的一部分,在这种情况下,反序列化方式不同?能否显示dto的外观?json不显示genderFilter的类型all@PatrickMagee我已经更新了q对于我们使用的一些实际DTO和枚举,我怀疑问题在于数组值解析??啊哈,好吧……这里的问题是我们通过SpringCodegen从预定义的模式生成这个枚举对象……我需要更改codegen模板,因为codegen中的模板是小胡子格式的。Thnx用于将我指向正确的方向。@simonC,我想在您的业务逻辑中添加第二步,检测过滤器阵列中的空值。好的,这可能是一个解决方案。是的
{
 
    "statuses": [
       "wrong value"
    ],
    "oddTypes": [
       "wrong value"
    ]
}