【问题标题】:Spring-MVC, InheritanceType.JOINED, and automatic mapping of JSON objects to entities with JacksonSpring-MVC、InheritanceType.JOINED 以及 JSON 对象到 Jackson 实体的自动映射
【发布时间】:2013-02-26 09:42:20
【问题描述】:

我们正在尝试编写一个 API 来创建不同类型的元素。这些元素具有 JPA 实体表示。以下代码显示了我们的基本元素结构(简化):

import javax.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Element {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column
    private String type;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

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

每个元素的实现看起来都不一样,但这个例子就足够了:

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class SpecializedElement1 extends Element {

    @Column
    private String attribute;

    public String getAttribute() {
        return attribute;
    }

    public void setAttribute(String attribute) {
        this.attribute = attribute;
    }

}

我们使用 Jackson,典型的控制器动作如下所示:

@RequestMapping(value = "/createElement", method = RequestMethod.POST)
@ResponseBody
public HashMap<String, Object> create(@RequestBody Element element) {
    HashMap<String, Object> response = new HashMap<String, Object>()
    response.put("element", element);
    response.put("status", "success");
    return response;
}

典型的请求正文如下所示:

{
    "type": "constantStringForSpecializedElement1"
    "text": "Bacon ipsum dolor sit amet cow bacon drumstick shankle ham hock hamburger."
}

如您所见:这不起作用,因为 Jackson 不知道如何将此对象映射到 SpecializedElement1。

问题是:我怎样才能做到这一点?

【问题讨论】:

    标签: jpa spring-mvc jackson


    【解决方案1】:

    我想通了。这就是解决方案:

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @JsonTypeInfo(
        // We use the name defined in @JsonSubTypes.Type to map a type to its implementation.
        use = JsonTypeInfo.Id.NAME,
        // The information that stores the mapping information is a property.
        include = JsonTypeInfo.As.PROPERTY,
        // The property is called "type".
        property = "type"
    )
    @JsonSubTypes({
            @JsonSubTypes.Type(value = SpecializedElement1.class, name = "specializedElement1"),
            @JsonSubTypes.Type(value = SpecializedElement1.class, name = "specializedElement2")
    })
    public class Element {
        // ....
    }
    

    此控制器操作按预期工作...

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> create(@RequestBody Element element) {
        if (element == null) {
            // Return an error response.
        }
        try {
            return elementService.update(element);
        } catch (Exception e) {
            // Return an error response.
        }
    }
    

    ...带着这个请求:

    POST /create/
    ... more headers ...
    Content-Type: application/json
    
    
    {
        "type": "specializedElement1"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-07
      • 2015-12-23
      • 2014-03-06
      • 2014-01-25
      相关资源
      最近更新 更多