如何配置Spring Data REST端点仅返回_embedded中的game数据?
Spring Data REST仅返回实体数据的实现方案
问题描述
使用Spring、Spring Data JPA和Spring Data REST为JPA仓库创建REST端点时,当前返回HAL格式响应,包含_embedded、_links和page字段:
{ "_embedded": { "game": [ ] }, "_links": { "self": { "href": "http://localhost:8080/game" }, "profile": { "href": "http://localhost:8080/profile/game" } }, "page": { "size": 20, "totalElements": 0, "totalPages": 0, "number": 0 } }
需求是仅返回_embedded中的game数据,移除_links及其他无关内容。
方法1:自定义Controller直接返回实体集合
放弃Spring Data REST自动生成的端点,自行编写Controller调用JPA Repository获取数据,直接返回实体列表:
@RestController @RequestMapping("/game") public class GameController { private final GameRepository gameRepository; public GameController(GameRepository gameRepository) { this.gameRepository = gameRepository; } @GetMapping public List<Game> getAllGames() { return gameRepository.findAll(); } }
这种方式完全由开发者控制返回格式,无需处理HAL包装,适合需要完全自定义响应的场景。
方法2:全局配置禁用Spring Data REST的HAL包装
通过配置类修改Spring Data REST的默认行为,关闭HAL格式的响应包装:
@Configuration public class RestConfig implements RepositoryRestConfigurer { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { // 设置GET请求直接返回实体数据 config.setReturnBodyForGet(ReturnBody.ALWAYS); // 清除默认的HAL媒体类型映射,替换为普通JSON config.getMediaTypeMappings().clear(); config.getMediaTypeMappings().put("json", MediaType.APPLICATION_JSON); } }
注意:此配置会全局生效,所有Spring Data REST生成的端点都会返回纯实体数据,不再包含HAL相关的_links和分页元数据。
方法3:使用ResponseBodyAdvice拦截并修改响应
通过自定义ResponseBodyAdvice拦截Spring Data REST的HAL响应,提取_embedded中的目标数据返回,实现局部或全局的响应修改:
@ControllerAdvice public class HalResponseInterceptor implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { // 仅处理Spring Data REST的分页模型或资源模型响应 return PagedModel.class.isAssignableFrom(returnType.getParameterType()) || ResourceModel.class.isAssignableFrom(returnType.getParameterType()); } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 处理分页响应,提取game集合 if (body instanceof PagedModel) { return ((PagedModel<?>) body).getContent(); } // 处理单个实体响应,提取实体内容 if (body instanceof ResourceModel) { return ((ResourceModel<?>) body).getContent(); } return body; } }
这种方式灵活性高,可通过判断请求路径或返回类型,针对特定接口做响应修改,不影响其他端点的HAL格式输出。
内容的提问来源于stack exchange,提问作者Dominic
相关产品推荐
相关产品推荐

