我們使用Jersey/Jackson作爲我們的REST應用程序。傳入的JSON字符串被傑克遜映射到後端的@Entity對象以被持久化。Jackson對象映射 - 將傳入的JSON字段映射到基類中的受保護屬性
問題來自我們用於所有實體的基類。它有一個受保護的id屬性,我們希望通過REST交換,因此當我們發送一個具有依賴關係的對象時,hibernate將自動通過它們的id獲取這些依賴關係。
Howevery,Jackson不會訪問setter,即使我們在子類中重寫它以公開。我們也嘗試使用@JsonSetter,但無濟於事。也許傑克遜只是着眼於基礎類,並認爲ID不是訪問,所以它跳過設置它...
@MappedSuperclass
public abstract class AbstractPersistable<PK extends Serializable> implements Persistable<PK> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private PK id;
public PK getId() {
return id;
}
protected void setId(final PK id) {
this.id = id;
}
子類:
public class A extends AbstractPersistable<Long> {
private String name;
}
public class B extends AbstractPersistable<Long> {
private A a;
private int value;
// getter, setter
// make base class setter accessible
@Override
@JsonSetter("id")
public void setId(Long id) {
super.setId(id);
}
}
現在如果有一些作爲我們的數據庫,我們希望通過REST資源來創建新B:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Response create(B b) {
if (b.getA().getId() == null)
cry();
}
用JSON字符串這樣{"a":{"id":"1","name":"foo"},"value":"123"}
。
傳入的B將有A引用但沒有ID。
有沒有辦法告訴傑克遜要麼忽略基類的setter或告訴它使用的子類的setter呢?
我剛剛發現了約@JsonTypeInfo
,但我不確定這是我需要什麼或如何使用它。
感謝您的幫助!
編輯
StaxMan有我擔心我在這裏失去了一些東西,所以我要添加servlet配置,因爲這是唯一的另外一點我能想到的任何地方可能出問題,如果我描述的行爲實際上應該是可以不添加XML註釋的setter(在我的答案中描述):
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>path.to.rest.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
我想你可能需要一個更設置啓用「POJO映射」,因爲它是不使用默認的一個? – StaxMan