Spring REST API中Pageable返回空对象问题求助
问题分析与解决方案
你遇到的核心问题是**@JsonView注解导致Spring Data Page对象的序列化被过滤**——虽然控制台能打印出有效数据,但Jackson序列化时,Page的内置属性(如content、pageNumber、totalElements等)没有被@JsonView(Views.GetView.class)标注,所以这些属性全部被过滤,最终返回空对象。
排查与解决步骤
1. 确认User实体类的@JsonView配置
首先确保User类中需要返回的字段都添加了对应View的注解,同时Views类必须是公开访问权限:
// Views类必须公开 public class Views { public static class GetView {} } // User实体类 public class User { @JsonView(Views.GetView.class) private Long id; @JsonView(Views.GetView.class) private String name; @JsonView(Views.GetView.class) private String username; @JsonView(Views.GetView.class) private String email; @JsonView(Views.GetView.class) private List<Role> roles; // getter、setter省略 }
2. 解决Page对象的JsonView序列化问题
Spring Data的Page接口及其实现类(如PageImpl)的方法没有自带@JsonView注解,需要通过Jackson Mixin扩展序列化规则:
步骤1:创建PageMixin类
import com.fasterxml.jackson.annotation.JsonView; import org.springframework.data.domain.Page; import java.util.List; public abstract class PageMixin<T> implements Page<T> { @JsonView(Views.GetView.class) @Override public abstract List<T> getContent(); @JsonView(Views.GetView.class) @Override public abstract int getNumber(); @JsonView(Views.GetView.class) @Override public abstract int getSize(); @JsonView(Views.GetView.class) @Override public abstract int getTotalPages(); @JsonView(Views.GetView.class) @Override public abstract long getTotalElements(); @JsonView(Views.GetView.class) @Override public abstract boolean hasNext(); @JsonView(Views.GetView.class) @Override public abstract boolean hasPrevious(); }
步骤2:注册Mixin到ObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.Page; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(Page.class, PageMixin.class); return mapper; } }
3. 替代方案:自定义分页响应DTO
如果不想配置Mixin,可以手动构建包含分页信息的响应对象,避免直接返回Page:
public class UserPageResponse { @JsonView(Views.GetView.class) private List<User> content; private int page; private int size; private long totalElements; private int totalPages; // 构造器 public UserPageResponse(List<User> content, int page, int size, long totalElements, int totalPages) { this.content = content; this.page = page; this.size = size; this.totalElements = totalElements; this.totalPages = totalPages; } // getter、setter省略 }
修改控制器方法:
@GetMapping("") @JsonView(Views.GetView.class) public ResponseEntity<UserPageResponse> getUsers(@ParameterObject Pageable pageable) { Page<User> allUsers = userRepository.findAll(pageable); UserPageResponse response = new UserPageResponse( allUsers.getContent(), allUsers.getNumber(), allUsers.getSize(), allUsers.getTotalElements(), allUsers.getTotalPages() ); return ResponseEntity.ok(response); }
完成以上配置后,接口就能正常返回包含分页数据和用户信息的响应了。
内容的提问来源于stack exchange,提问作者BernardA
相关产品推荐
相关产品推荐

