【发布时间】:2011-12-15 10:30:21
【问题描述】:
很简单的问题,很难找到答案:
我想在 JSON 中序列化我的 POJO JPA 实体,其引用类似于 Dojo,以便与 dojox.data.JsonRestStore 一起使用。
服务器部分是用 Spring MVC 和 HttpConverters 制作的,使其成为一个 RESTfull web-app。我正在使用 JacksonJson 将 JPA 实体转换为 JSON。
正如很多人一样,我确实有多个参考的问题。 @JsonBackReference 和 @JsonManagedReference 不能解决问题!
考虑这个基本示例:
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable=false)
private String field;
@OneToMany(mappedBy = "b")
private List<B> bs;
}
public class B {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private A a;
}
使用基本的 Jackson Json 转换器,您可以获得类似这样的东西(考虑到您已经放置了 @JsonBackReference 和 @JsonManagedReference):
{ id:1, fieldB:"bbbbb", a: { id:1, fieldA: "aaaaaa" }}
在一个具体的应用程序中,在大多数情况下,从 A 对象中获取 bs 列表是没有意义的。但是知道 B.a 字段中的 A 对象是什么类型很重要(至少对我而言)。
现在,问题在于被复制的引用,您最终可能会得到一些严重的大 JSON,其中没有太多数据。
Dojo 框架提供了此处解释的参考标准:http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo/ 和 http://dojotoolkit.org/reference-guide/dojox/data/JsonRestStore.html.
所以我正在搜索的是一种将其定义如下的方法:
{ id:1, fieldB:"bbbbb", a: { $ref: "getA/1"}}
第一个问题:Jackson 显然不知道您将使用什么 url 作为参考。
为了解决这个问题,我制作了非常简单的界面,如下所示:
public interface EntityWithId {
public Long getId();
public void setId(Long id);
}
这个接口由我所有的实体实现,我做了这个非常简单的 JsonSerializer:
public class EntityIdSerializer extends JsonSerializer<EntityWithId> {
@Override
public void serialize(EntityWithId value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("$ref", "db/" + value.getClass().getSimpleName() + "/" + value.getId().toString());
jgen.writeEndObject();
}
}
有了这两个,我得到了所需的 JSON,将 @JsonSerialize(using = EntityIdSerializer.class) 添加到 @ManyToOne 字段。
没有更多的标准方法了吗? Dojo dojox.data.JsonRestStore 听起来很有希望,因为您可以将它与许多 Dijits 小部件结合使用,但这样做和尝试真的是一件好事吗?我的 REST 应用程序不会受到 Dojo 的限制吗?
感谢您的回答!
【问题讨论】:
标签: json spring-mvc jackson dojo