【问题标题】:handle InvalidTypeIdException with jackson用杰克逊处理 InvalidTypeIdException
【发布时间】:2020-03-16 18:46:38
【问题描述】:

这是使用 JsonType 和 JsonSubTypes 注释的基类,需要强制“类型”字段。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes(value = {
    @JsonSubTypes.Type(value = SubA.class, name = "A"),
    @JsonSubTypes.Type(value = SubB.class, name = "B")
})
public abstract class Base {
    private String type;

    public String getType()
    {
        return type;
    }

    public void setType(String type)
    {
        this.type = type;
    }
}

下面的类包装了上面的类并在控制器中使用。这个包装类已经采用了“类型”,需要将其传递给上面的 Base 类

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
class BaseWrapper {
    @NotBlank
    private String type;
    @NotNull
    @Valid
    private Base base;

}

最后,验证在控制器中

@PostMapping("/createBase")
public ResponseEntity<ResponseDto> createBase(@RequestBody @Valid BaseWrapper)
{    
    ...
}

在 Spring Boot 中与控制器验证一起使用的 JSON 示例 -

{
  "type":"A",
  "base": {
     "type:"A",
     //fields of A
  }
}

如何从基础本身内部删除重复类型,如下所示。这给了杰克逊的InvalidIdException

{
  "type":"A",
  "base": {
     //fields of A
  }
}

我知道使用自定义反序列化器是一种方法,但 JsonTypeInfo、JsonSubTypeInfo 和默认完成的所有验证均不适用,所有内容都必须手工制作。

是否可以修复两次所需的类型,以便仅将外部 Json 类型传播到内部并且 Jackson 理解它?

【问题讨论】:

    标签: java spring spring-boot jackson


    【解决方案1】:

    您可以使用JsonTypeInfo.As.EXTERNAL_PROPERTY,但请注意 javadoc:

    包含机制类似于 PROPERTY,只是属性是 在层次结构中包含更高一级,即作为同级财产 与要键入的 JSON 对象级别相同。请注意,此选择只能是 用于属性,而不是类型(类)。试图将其用于 类将导致包含基本属性的策略。

    因此,这不适用于类级别,但适用于包装器中的属性

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonIgnoreProperties(ignoreUnknown = true)
    @Getter
    @Setter
    public static class BaseWrapper {
        @NotBlank
        private String type;
    
        @NotNull
        @Valid
        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type", visible = true)
        @JsonSubTypes(value = {
                @JsonSubTypes.Type(value = SubA.class, name = "A"),
                @JsonSubTypes.Type(value = SubB.class, name = "B")
        })
        private Base base;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-31
      • 2012-09-13
      • 2023-03-27
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 2017-04-20
      • 1970-01-01
      • 2015-02-28
      相关资源
      最近更新 更多