Хотя решение @bigbounty отличное, и я думаю, что View
s, в дополнение к c DTO
s, являются способом go в целом, в этом случае оно может быть неприменимо, потому что , для одного и того же класса Person
нам действительно нужны два разных поведения в одном и том же представлении.
@JsonFilter
s можно использовать для решения проблемы.
Это Метод main
вычисляет график, который вам нужен:
public static void main(String[] args) throws JsonProcessingException {
final PropertyFilter departmentFilter = new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField
(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer)
throws Exception {
if (include(writer)) {
final String name = writer.getName();
if (!name.equals("deputy") && !name.equals("staff")) {
writer.serializeAsField(pojo, jgen, provider);
return;
}
if (name.equals("staff")) {
return;
}
// Ideally it should not be muted.
final Department department = (Department)pojo;
final Person deputy = department.getDeputy();
deputy.setCode(-1);
writer.serializeAsField(department, jgen, provider);
} else if (!jgen.canOmitFields()) { // since 2.3
writer.serializeAsOmittedField(pojo, jgen, provider);
}
}
@Override
protected boolean include(BeanPropertyWriter writer) {
return true;
}
@Override
protected boolean include(PropertyWriter writer) {
return true;
}
};
final PropertyFilter personFilter = new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField
(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer)
throws Exception {
if (include(writer)) {
if (!writer.getName().equals("code")) {
writer.serializeAsField(pojo, jgen, provider);
return;
}
int code = ((Person) pojo).getCode();
if (code >= 0) {
writer.serializeAsField(pojo, jgen, provider);
}
} else if (!jgen.canOmitFields()) { // since 2.3
writer.serializeAsOmittedField(pojo, jgen, provider);
}
}
@Override
protected boolean include(BeanPropertyWriter writer) {
return true;
}
@Override
protected boolean include(PropertyWriter writer) {
return true;
}
};
final Department department = new Department();
final Person head = new Person("John", 123);
final Person deputy = new Person("Jack", 234);
final List<Person> personList = Arrays.asList(new Person("Tom", 345), new Person("Matt", 456));
department.setHead(head);
department.setDeputy(deputy);
department.setStaff(personList);
final ObjectMapper mapper = new ObjectMapper();
final FilterProvider schema1Filters = new SimpleFilterProvider()
.addFilter("deparmentFilter", departmentFilter)
.addFilter("personFilter", personFilter)
;
mapper.setFilterProvider(schema1Filters);
final String withSchema1Filters = mapper.writeValueAsString(department);
System.out.printf("Schema 1:\n%s\n", withSchema1Filters);
// You must maintain the filters once the classes are annotated with @JsonFilter
// We can use two no-op builtin filters
final FilterProvider schema2Filters = new SimpleFilterProvider()
.addFilter("deparmentFilter", SimpleBeanPropertyFilter.serializeAll())
.addFilter("personFilter", SimpleBeanPropertyFilter.serializeAll())
;
mapper.setFilterProvider(schema2Filters);
final String withSchema2Filters = mapper.writeValueAsString(department);
System.out.printf("Schema 2:\n%s\n", withSchema2Filters);
}
Чтобы этот код работал, вы должны аннотировать класс Department
с помощью:
@JsonFilter("deparmentFilter")
И Person
class с:
@JsonFilter("personFilter")
Как видите, Джексон также предоставляет несколько встроенных фильтров.
Этот код тесно связан с тестовыми классами, которые вы предложили, но его можно расширить таким образом, чтобы делает его более универсальным c.
Пожалуйста, посмотрите SimpleBeanPropertyFilter , чтобы увидеть примеры того, как создать свой собственный фильтр.