我正在尝试将POJO序列化为JSON,但却陷入循环引用问题。我知道如何使用@JsonBackReference
和@JsonManagedReference
处理一对多和反向关系。
我的问题是双向的多对多关系(例如,一个学生可以有很多课程,每个课程可以有很多学生注册),父母参考儿童和孩子参考回到父母,这里我的序列化器死了。根据我的理解,我不能在这里使用@JsonBackReference
,因为属性的值类型必须是bean:它不能是Collection,Map,Array或枚举。
有人可以告诉我如何处理这种情况吗?
答案 0 :(得分:9)
您可以在关系的一侧使用@JsonIgnoreProperties("someField")
(注释是类级别)。或@JsonIgnore
答案 1 :(得分:2)
由于@Bozho回答使用@JsonIgnoreProperties,试试这个,它对我有用。
以下是我的@JsonIgnoreProperties模型:
@Entity
public class Employee implements Serializable{
@ManyToMany(fetch=`enter code here`FetchType.LAZY)
@JoinTable(name="edm_emp_dept_mappg",
joinColumns={@JoinColumn(name="emp_id", referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="dept_id", referencedColumnName="id")})
@JsonIgnoreProperties(value="employee")
Set<Department> department = new HashSet<Department>();
}
@Entity
public class Department implements Serializable {
@ManyToMany(fetch=FetchType.LAZY, mappedBy="department")
@JsonIgnoreProperties(value="department")
Set<Employee> employee = new HashSet<Employee>();
}
在@JsonIgnoreProperties的value属性中,我们需要提供counter(相关)模型的集合类型属性。
答案 2 :(得分:0)
您还可以使用Dozer映射将POJO转换为Map并排除字段。例如,如果我们有两个类PojoA和PojoB具有双向关系,我们定义像这样的映射
<mapping map-id="mapA" map-null="false">
<class-a>com.example.PojoA</class-a>
<class-b>java.util.Map</class-b>
<field>
<a>fieldA</a>
<b>this</b>
</field>
<field map-id="mapB">
<a>pojoB</a>
<b>this</b>
<b-hint>java.util.Map</b-hint>
</field>
</mapping>
<mapping map-id="mapB" map-null="false">
<class-a>com.example.PojoB</class-a>
<class-b>java.util.Map</class-b>
<field-exclude>
<a>pojoA</a>
<b>this</b>
</field-exclude>
</mapping>
然后定义一个bean,将上面的推土机映射文件设置为属性。
<bean id="mapper" class="org.dozer.DozerBeanMapper">
<property name="mappingFiles">
<list>
<value>dozerMapping.xml</value>
</list>
</property>
</bean>
然后在你序列化的课程中
public class TestClass
{
@Autowired
DozerBeanMapper mapper;
public Map<String,Object> serializeObject(PojoA pojoA)
{
return ((Map<String, Object>) mapper.map(pojoA, Map.class, "mapA"));
}
}
答案 3 :(得分:0)
阐述@Bozho已经提到的内容......
我现在因为我正在使用Google Cloud Endpoints而遇到了Jackson 1,因此即使Jackson 2已经出局一段时间,这仍然可以帮助一些人。即使我不需要反序列化整个对象,仍然非常需要引用。
我将@JsonIgnore放在导致循环引用的字段上,但随后为每个引用创建了一个新的getter,以便在我的API中仍然返回一个扁平引用。
@JsonIgnore
private FooClass foo;
public String getFooKey()
...
使用Cloud Endpoints,这会导致在GET有效负载中返回一个扁平的“fooKey”,同时省略“foo”。
答案 4 :(得分:-1)
如果您有集合对象,请将其设为
collection<object> listobj
var jsonObj = from c in listobj
select new
{
Prop1 = c.Prop1
...
}
这应该工作,你现在得到的对象可以是json序列化和干净的