0

さまざまなタイプの要素を作成する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にマップする方法を知らないため、これは機能しません。

問題は、どうすればこれを機能させることができるかということです。

4

1 に答える 1

2

私はそれを考え出した。それが解決策です:

@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"
}
于 2013-03-14T18:25:15.467 に答える