@OneToMany getter有时返回对象,有时返回id(在数组中)

时间:2016-03-12 12:40:28

标签: java json spring-boot jackson

我与学校之间存在@OneToMany关系。

如果我在前端加载老师,我会得到一份老师名单;但其中一些不是对象ID ....

@OneToMany
@JsonManagedReference(value = "teachers")
@JsonIgnore // only admins
private Set<Teacher> teachers = new HashSet<>();

这是@JsonIgnore,因为我在控制器中拨打了一个额外的电话,以防止加载时间过长。

接下来我不删除数据库中的条目 - 我只是禁用它们;这是带过滤器的吸气剂:

@JsonIgnore // only admin
public Set<Teacher> getTeachers() {
    return teachers.stream().filter(DbModel::isEnabled).collect(Collectors.toSet());
}

最后在控制器中进行访问:

@RequestMapping(value = "/{schoolId}/teacher", method = RequestMethod.GET)
public Set<Teacher> readTeacher(@PathVariable long schoolId, @RequestParam("teacher") long adminId) {
    School school = schoolRepository.findOne(schoolId);
    Teacher admin = teacherRepository.findOne(adminId);

    if (school == null) {
        throw new NotFoundException(School.class, schoolId);
    }
    if (admin == null) {
        throw new NotFoundException(Teacher.class, adminId);
    }

    if (!admin.isAdmin(school)) {
        throw new NoAccessRightException();
    }

    return school.getTeachers();
}

如何始终只获取对象?

更新:示例输出:

[
  {
    "@id": 1,
    "id": 1,
    // contend
  },
  {
    "@id": 5,
    "id": 2,
    // contend
  },
  2,
  {
    "@id": 6,
    "id": 8,
    // contend
  },
  4,
  3
]

另一个问题:我可以只对一个电话进行投射吗?

1 个答案:

答案 0 :(得分:1)

要忽略试试这个。

@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class MyClass {

     @JsonIgnore // only admins
     private Set<Teacher> teachers = new HashSet<>();

}

所以杰克逊将包括所有属性,但标有@JsonIgnore的属性除外。

要仅添加子项的ID,您需要一个自定义序列化程序。

@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class School {

     @JsonSerialize(using = TeachersSerializer .class)
     private Set<Teacher> teachers = new HashSet<>();

}

序列化器:

public class TeachersSerializer extends JsonSerializer<Set<Teacher>> {
    @Override
    public void serialize(Set<Teacher> values, JsonGenerator jgen, SerializerProvider provider) throws IOException {
       jgen.writeStartArray();
       for (Teacher value : values) {
          jgen.writeStartObject();
          jgen.writeNumberField("id", value.getId());
          jgen.writeEndObject();
       }
       jgen.writeEndArray();
    }
}

如果您只想在此控制器中返回,请创建一个Teachers类。

@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Teachers implements Serializable {
     @JsonSerialize(using = TeachersSerializer.class)
     private Set<Teacher> teachers = new HashSet<>();

     public Teachers(Set<Teacher> teachers){
         this.teachers = teachers;
     }
}

在您的控制器中:

public class Controller {

   public Teachers readTeacher(...){
      ....
      return new Teachers(school.getTeachers());
   }
}