项目中都会使用 Result 作为接口返回值,分页查询接口中会使用 Result<PageInfo<T>>,T 是实际的返回对象,现在我想使用 @JsonView,发现返回值直接变为空了。我尝试在 ObjectMapper 中增加 Result 的 Serializer 确实可以满足我的要求。但是感觉不太优化,所有接口返回值都是 Result ,影响太大.
下面是我的代码片段
@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Result.class, new ResultJsonSerializer(objectMapper));
objectMapper.registerModule(simpleModule);
return objectMapper;
}
@Override
public void serialize(Result<T> page, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
gen.writeStartObject();
gen.writeStringField("code", page.getCode());
gen.writeStringField("msg", page.getMsg());
gen.writeStringField("timestamp", page.getTimestamp());
gen.writeStringField("requestId", page.getRequestId());
gen.writeFieldName("data"); // 将 "data" 字段名称写入
if (page.getData() instanceof PageInfo) {
gen.writeStartObject(); // 开始 JSON 对象
gen.writeBooleanField("isFirstPage", ((PageInfo<?>) page.getData()).isIsFirstPage());
gen.writeBooleanField("hasNextPage", ((PageInfo<?>) page.getData()).isHasNextPage());
gen.writeBooleanField("isLastPage", ((PageInfo<?>) page.getData()).isIsLastPage());
gen.writeBooleanField("hasPreviousPage", ((PageInfo<?>) page.getData()).isHasPreviousPage());
gen.writeNumberField("pages", ((PageInfo<?>) page.getData()).getPages());
gen.writeNumberField("nextPage", ((PageInfo<?>) page.getData()).getNextPage());
gen.writeNumberField("navigatePages", ((PageInfo<?>) page.getData()).getNavigatePages());
gen.writeNumberField("pageNum", ((PageInfo<?>) page.getData()).getPageNum());
gen.writeNumberField("pageSize", ((PageInfo<?>) page.getData()).getPageSize());
gen.writeNumberField("size", ((PageInfo<?>) page.getData()).getSize());
gen.writeNumberField("prePage", ((PageInfo<?>) page.getData()).getPrePage());
gen.writeNumberField("navigateFirstPage", ((PageInfo<?>) page.getData()).getNavigateFirstPage());
gen.writeNumberField("navigateLastPage", ((PageInfo<?>) page.getData()).getNavigateLastPage());
gen.writeNumberField("startRow", ((PageInfo<?>) page.getData()).getStartRow());
gen.writeNumberField("endRow", ((PageInfo<?>) page.getData()).getEndRow());
gen.writeNumberField("total", ((PageInfo<?>) page.getData()).getTotal());
gen.writeArrayFieldStart("list");
objectMapper.writerWithView(serializerProvider.getActiveView()).writeValue(gen, ((PageInfo<?>) page.getData()).getList());
gen.writeEndArray();
gen.writeEndObject(); // 结束 JSON 对象
}else {
objectMapper.writerWithView(serializerProvider.getActiveView()).writeValue(gen, page.getData());
}
gen.writeEndObject();
}
1
mmdsun 2023-11-02 19:27:31 +08:00 via iPhone 1
再之前那个帖子也回复了你哈,说一个我的方法:这种情况嵌套类每一层 Result 和 PageInfo 、T 都需要加 @JsonView 的注解。你返回为空可能就是因为嵌套类中有类没有加 @JsonView 。这个注解可以加到类上的,效果就是所有字段控制都可见。
另外在控制器上使用的 T 类的(假设是 Apple 类) @JsonView(AppleView.class),你可能会说这三个类 Result<PageInfo<Apple>>是怎么关联的? 还有一个重要的步骤就是 AppleView 接口需要继承 Result 、PageInfo 的 View 接口。(Java 接口支持多继承) ——这样不会改动很多,因为默认还是所有字段可见的。你只需要控制的时候在对 T 类用 @JsonView 控制就行。(可能还有其他更好的方法就要查文档了,我也记得不是很清楚。 |