我有一个javaEE应用程序,其中有两个实体,它们可以持久化到数据库中。两个实体都具有双向关联。
第一个实体:
@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Child.class)
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne(fetch= FetchType.LAZY)
private Father father;
}第二实体
@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Father.class)
public class Father implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne(fetch= FetchType.LAZY)
private Child child;
}这两个文件都是通过重新源公开的,如:
@Path("father")
@Stateless
public class FatherResource{
@Context
private UriInfo uri;
@Inject FatherDao fatherDao;
public FatherResource() {
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Father> getFathers() {
//TODO return proper representation object
return fatherDoa.getFathers();
}
}还有一个DAO,它只是从数据库中获取父对象。
现在的问题是,我得到了一个圆形的json结构。所以,就像:
{ "id":"1", "child": {"id":"1", "father": {"id":"1", "child":{"id":"1", [...] 我只想见见这孩子一次。
我试着用:
@JsonIgnoreProperties({"child"}) //above the class
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") //above the class
@JsonIgnore //above the property我想得到的是:
{ "id":"1", "child": {"id":"1"}}我在用
JDK 7
JaxRS
Jackson
Hibernate/Eclipselink
Glassfish 4.0另一个不起作用的测试:
@Entity
@JsonSerialize
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="id", scope=Object.class)
public class Father implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne(fetch= FetchType.LAZY)
private Child child;
}ApplicationConfig.java:
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
// following code can be used to customize Jersey 2.0 JSON provider:
try {
Class jsonProvider = Class.forName("org.glassfish.jersey.jackson.JacksonFeature");
} //...
//..beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="annotated">
</beans>发布于 2014-04-23 23:00:57
您可以在返回列表之前编写一个将father设置为null的循环。这样,您就不会给JSON序列化程序提供一个循环数据结构。
这个解决办法看上去可能不是很干净,但它是有效的,因为没有人回答这个问题,但我认为它是值得一提的。
发布于 2014-12-05 12:46:48
下面是一个例子,它有效地解决了您的问题。Jackson能够序列化您的递归。看看这个:
3 POJO (A,B,C)和一次试验。用杰克逊2.2.3测试。
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class RecClassA {
private RecClassA mySelf;
private RecClassB b;
private String value = "AV";
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public RecClassA getMySelf() {
return mySelf;
}
public void setMySelf(RecClassA mySelf) {
this.mySelf = mySelf;
}
public RecClassB getB() {
return b;
}
public void setB(RecClassB b) {
this.b = b;
}
}
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class RecClassB {
private String value = "BV";
private RecClassC c;
private RecClassA a;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public RecClassC getC() {
return c;
}
public void setC(RecClassC c) {
this.c = c;
}
public RecClassA getA() {
return a;
}
public void setA(RecClassA a) {
this.a = a;
}
}
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class RecClassC {
private String value = "CV";
private RecClassA a;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public RecClassA getA() {
return a;
}
public void setA(RecClassA a) {
this.a = a;
}
}
import org.testng.annotations.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperRecursionTest {
private ObjectMapper om = new ObjectMapper();
@Test
public void simpleWriteTest() throws JsonProcessingException{
RecClassA a = new RecClassA();
String result = om.writeValueAsString(a);
System.out.println("simpleWriteTest: " + result);
}
@Test
public void simpleRecursionWriteTest() throws JsonProcessingException{
RecClassA a = new RecClassA();
a.setMySelf(a);
String result = om.writeValueAsString(a);
System.out.println("simpleRecursionWriteTest: " + result);
}
@Test
public void abbaRecursionWriteTest() throws JsonProcessingException{
RecClassA a = new RecClassA();
RecClassB b = new RecClassB();
a.setB(b);
b.setA(a);
String result = om.writeValueAsString(a);
System.out.println("abbaRecursionWriteTest: " + result);
}
@Test
public void abcaRecursionWriteTest() throws JsonProcessingException{
RecClassA a = new RecClassA();
RecClassB b = new RecClassB();
RecClassC c = new RecClassC();
a.setB(b);
b.setC(c);
c.setA(a);
String result = om.writeValueAsString(c);
System.out.println("abcaRecursionWriteTest: " + result);
}
}在这里,测试的结果:
abbaRecursionWriteTest: {"@id":1,"mySelf":null,"b":{"@id":2,"value":"BV","c":null,"a":1},"value":"AV"}
abcaRecursionWriteTest: {"@id":1,"value":"CV","a":{"@id":2,"mySelf":null,"b":{"@id":3,"value":"BV","c":1,"a":null},"value":"AV"}}
simpleRecursionWriteTest: {"@id":1,"mySelf":1,"b":null,"value":"AV"}
simpleWriteTest: {"@id":1,"mySelf":null,"b":null,"value":"AV"}https://stackoverflow.com/questions/20584682
复制相似问题