Spring boot SpringBoot rest验证不会因错误的枚举输入而失败
我有一个SpringBoot rest POST端点,在主体中我发布了一个枚举值。此调用不会因输入错误的值而失败。我希望rest调用失败,而不是为无法反序列化的值返回null 我已经尝试了以下自定义ObjectMapper配置,但我作为enum放入的任何错误输入都会反序列化为nullSpring 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
@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"
]
}