【问题标题】:Spring @RequestBody containing a list of different types (but same interface)Spring @RequestBody 包含不同类型的列表(但接口相同)
【发布时间】:2013-06-19 06:57:52
【问题描述】:

假设我有一个域类:

    public class Zoo{
        private List<Animal> animals;
        ....

其中 Animal 是具有不同实现(Cat、Dog)的接口。假设我希望能够保存 Zoo 对象:

    @RequestMapping(value = "/zoo", method = RequestMethod.POST)
    public @ResponseBody void save(@RequestBody Zoo zoo) {
    ....

我想发送一个 json - 比如:

    {
        animals:[
            {type:'Cat', whiskers-length:'3'},
            {type:'Dog', name:'Fancy'}
        ]
    }

如何告诉 spring MVC 在 type=='Cat' 时将动物映射到 Cat 类型,并在 type=='Dog' 时将其映射到 Dog 类?

【问题讨论】:

  • 很抱歉与无效的 json 混淆。但它仍然没有解决我的问题,即从 json 对象 {type:'Cat',whiskersLength:'3'} 到 Cat 类的映射。 Zoo 类只知道动物列表包含动物。但是 json 反序列化器如何知道特定 json 对象使用 Animal 接口(Dog 或 Cat)的哪个实现?

标签: java json spring spring-mvc


【解决方案1】:

你应该使用Jackson注解@JsonTypeInfo@JsonSubTypes来实现多态json。注释在Animal 基类上。

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "Cat")})
public abstract class Animal {

}

【讨论】:

  • 这对于 2 个子类型(猫和狗)来说看起来很棒,但是如果您有一个庞大的子类型列表怎么办?动物园里有更多种类的动物:)
  • 是否可以在 Cat 或 Dog 上添加一些注释,而不在动物上添加 @JsonSubTypes
  • 不要忘记 visible = true 以防您不想丢失 json 中的属性“类型”,@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "类型”,可见 = true)
【解决方案2】:

现在有一个更简单的注释:

@JsonRootName("dog")
public class Dog extends Animal {...}

注释的参考可以在fasterxml.github上找到

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-28
    • 2011-07-16
    • 2022-01-27
    • 2013-10-13
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    相关资源
    最近更新 更多