开发者社区> 问答> 正文

用JsonType处理InvalidTypeIdException

这是用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是JsonType给的。

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

我知道使用自定义反序列化器是一种方法,但是JsonTypeInfo,JsonSubTypeInfo和默认情况下进行的所有验证均不适用,并且所有操作都必须手工制作。

是否可以将所需的类型固定两次,以便仅将外部Json类型传播到内部,而Jackson可以理解?

问题来源:Stack Overflow

展开
收起
montos 2020-03-22 08:56:28 1454 0
1 条回答
写回答
取消 提交回答
  • 您可以使用, JsonTypeInfo.As.EXTERNAL_PROPERTY但请注意javadoc

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

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

    @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;
    
    }
    

    回答来源:Stack Overflow

    2020-03-22 08:57:56
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载