9

我正在尝试将 POJO 序列化为 JSON,但陷入循环引用问题。@JsonBackReference我知道如何使用and处理一对多和反向关系@JsonManagedReference

我的问题是双向多对多关系(例如,一个学生可以有很多课程,每门课程可以有很多学生注册),父母参考孩子和孩子参考回到父母,这里我的序列化器死了。根据我的理解,我不能@JsonBackReference在这里使用,因为属性的值类型必须是 bean:它不能是 Collection、Map、Array 或枚举。

有人可以告诉我如何处理这种情况吗?

4

5 回答 5

9

您可以@JsonIgnoreProperties("someField")在关系的一侧使用(注释是类级别的)。或者@JsonIgnore

于 2011-03-17T22:22:04.250 回答
3

正如@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(related) 模型的集合类型属性。

于 2016-01-20T14:09:46.117 回答
0

阐述@Bozho 已经提到的内容......

我现在坚持使用 Jackson 1,因为我使用的是 Google Cloud Endpoints,所以即使 Jackson 2 已经发布了一段时间,这仍然可能对某些人有所帮助。即使我不需要反序列化整个对象,引用仍然是非常必要的。

我将@JsonIgnore 放在导致循环引用的字段上,但随后为每个字段创建了一个新的getter,以便在我的API 中仍然返回一个平面引用。

@JsonIgnore
private FooClass foo;

public String getFooKey()
...

使用 Cloud Endpoints,这会导致在 GET 负载中返回一个扁平的“fooKey”,同时省略“foo”。

于 2013-11-11T20:33:58.823 回答
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"));
     }
}

推土机手册在这里

于 2011-03-18T04:57:19.477 回答
-1

如果你有集合对象,让它成为

collection<object> listobj 

var jsonObj = from c in listobj
                  select new
                 {
                   Prop1 = c.Prop1
                    ...
                 }

这应该可以工作,并且您现在获得的对象可以被 json 序列化并且它是干净的

于 2011-03-17T23:28:16.923 回答