springmvc用jackson返回json无限循环
springmvc使用jackson转json解决双向关联关系(例如一对多)循环调用。目前只是避开了循环调用,并不是真正的从根本上解决。就算用ObjectMapper Hibernate4Module也是解决懒加载转json的问题。
问题简说
实体类:老师Teacher.java
@OneToMany(fetch= FetchType.LAZY,cascade = CascadeType.ALL) @JoinColumn(name="teacher_id") public Set<Student> getStudents() { return students; }
实体类:学生Student.java
@ManyToOne @JoinColumn(name="teacher_id") public Teacher getTeacher() { return teacher; }
服务层:学生服务层StudentServiceImpl.java
@Override @Transactional(readOnly = true) public Student findById(Long id){ Student student = studentRepository.findOne(id); //模拟用到了关联数据,或者使用了自动映射复制到vo、dto等等 Teacher teacher = student.getTeacher(); Set<Student> students = teacher.getStudents(); System.out.println(students); return student; }
控制层:返回json数据到前台
@RequestMapping(value = "/find", method = RequestMethod.GET) @ResponseBody public Student find(HttpServletRequest request, HttpServletResponse response){ Student student = studentService.findById(1L); return student; }
由于hibernate双向关联关系,查出来的实体对象返回前台输出json,会循环嵌套。如:
{"id":1,"name":"Student-1","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":[{"id":2,"name":"Student-2","teacher":{"id":1,"name":"Teacher","students":... ...... ......
解决方法
1、最简单的办法
在返回的时候吧循环嵌套设置为空,或mapping转vo,dto的时候过滤该字段。
缺点:对象复杂时比较麻烦,用mapper复制对象又要考虑过滤字段操作。
Student student = studentRepository.findOne(id); Teacher teacher = student.getTeacher(); teacher.setStudents(null); return student;
输出:
{"id":1,"name":"Student-1","teacher":{"id":1,"name":"Teacher","students":null}}
2、springmvc返回jackson注解处理
@JsonBackReference:
标记在子类对父类的引用变量上,标注的属性在将对象转换为json数据时,会被忽略。
它的作用相当于@JsonIgnore,此时可以没有@JsonManagedReference。
@JsonManagedReference:
标记在父类对子类的引用变量上,标注的属性在被对象转换为json数据时,不会被忽略。
如果没有它在json数据转换为对象时,不会注入@JsonBackReference标记属性。
@JsonIgnore:
直接忽略某个属性,以断开无限递归,序列化或反序列化均忽略。
缺点:学生类找不到老师类的ID了,整个属性都被忽略掉了,如果需要,要另外起属性定义赋值如return teacher.getId();
用户类(子)多的一端
@JsonBackReference private Teacher teacher;
老师类(父)一的一端
@JsonManagedReference private Set<Student> students;
输出:
{"id":1,"name":"Student-1"}
后面如果发现有更好的办法再补上。
原创文章,转载请注明出处:https://www.weizhixi.com/article/64.html