删除 Spring RepositoryRestResource 中的“_embedded”属性

Posted

技术标签:

【中文标题】删除 Spring RepositoryRestResource 中的“_embedded”属性【英文标题】:Removing "_embedded" property in Spring RepositoryRestResource 【发布时间】:2018-11-11 18:22:33 【问题描述】:

我正在使用 Spring Boot 2.0.2(带有 oAuth2 2.3.3)和 HATEOAS(我有一个依赖文件说我正在使用它,即使我的重点不是那个)来构建一个 RestAPI。我可以毫无问题地提出请求并获得回复。但是,当我请求集合/页面时,我会在“_embedded”对象中得到响应,如下所示:


  "_embedded" : 
    "users" : [ 
      "firstName" : "Stuff",
      "lastName" : "ToDo",
      ...
    , 
      "firstName" : "Things1",
      "lastName" : "Does",
      ...
   ],
  "_links" : 
    "self" : 
      "href" : "http://localhost:8080/user?page,size,sort",
      "templated" : true
    ,
    "profile" : 
      "href" : "http://localhost:8080/profile/user"
    ,
    "search" : 
      "href" : "http://localhost:8080/user/search"
    
  ,
  "page" : 
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  

是否可以删除“_embedded”属性或将其替换为“内容”之类的东西?

我尝试在我的 application.yml 上添加此属性:

弹簧: 讨厌: 使用-hal-as-default-json-media-type: false

我也试过不带“-”:

useHalAsDefaultJsonMediaType: false

运气不好。我还尝试在请求中添加以下标头值,但它无法正常工作:

"Accept: application/hal+json" 给出相同的响应 要么 "Accept: application/x-spring-data-verbose+json" 给我一个 406 Not Acceptable。

这是我的资源:

@RepositoryRestResource(collectionResourceRel = "user", path = "user")
@PreAuthorize("hasRole('ROLE_ADMIN'")
public interface UserRepositoryAndResource extends PagingAndSortingRepository<User, Long> 

    public User findByLogin(@Param("login") String login);

    public Page<User> findByLoginContaining(@Param("login") String login, Pageable pageable);



我还有一个控制器,用于在无会话上下文中公开当前用户。我不想谈这个:

@Controller
public class UserForTokenController 

    private UserRepositoryAndResource repo;

    @Autowired
    public UserForTokenController(
            UserRepositoryAndResource repo) 
        this.repo = repo;
    

    @GetMapping("user/current")
    public ResponseEntity<UserModel> getForToken(OAuth2Authentication auth) throws UserNotFoundException 
        String authUser = (String) auth.getPrincipal();
        String login = authUser;
        User user = Optional.of(repo.findByLogin(login)).orElseThrow(() -> new UserNotFoundException());
        return ResponseEntity.ok(UserModel.build(user));
    


目前真的不知道该做什么。 提前致谢。

【问题讨论】:

如果您不确定 yml 文件中的属性,请添加包含您的属性的 bootstrap.propertiesapplication.properties (spring.hateoas.use-hal-as-default-json-media-type=false) 【参考方案1】:

免责声明:我还没有使用过 Spring HATEOAS。


我将假设您使用的是 Spring 4.1 或更高版本,并且您在 rest 控制器中使用您的 @RequestMapping 方法返回一个对象。

要修改响应,您可以实现ResponseBodyAdvice 接口,该接口在响应写回客户端之前调用。 MyResponse 类包含我要在此示例中修改的内容。它有一个名为 content 的 String 属性。

如果我的@RequestMapping 方法如下所示:

@RequestMapping("/q50646303")
  public MyResponse q50646303() 
    MyResponse myResponse = new MyResponse();
    myResponse.setContent("content");
    return myResponse;
  

我可以像这样更改响应的内容:

@RestControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice<MyResponse> 

  @Override
  public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) 
    return MyResponse.class == methodParameter.getParameterType();
  

  @Override
  public MyResponse beforeBodyWrite(MyResponse myResponse, MethodParameter methodParameter, MediaType mediaType,
      Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest,
      ServerHttpResponse serverHttpResponse) 
    //Change your content here
    myResponse.setContent("edited content");
    return myResponse;
  

如果我调用 URL "content":"edited content",则会打印出来。也许您可以使用它以您想要的方式编辑响应?

对于未来的问题,如果您包含更多信息,例如使用的框架版本或相关代码(在本例中为您的 RestController),将会很有帮助。

【讨论】:

首先感谢您的回复。在此之后我将编辑我的主要帖子。我实际上正在使用@RepositoryRestResource。我不确定我是否可以按照您的建议进行操作,但无论如何我都会尝试。再次感谢。编辑:用更多相关信息更新主帖 感谢您更新您的答案 :) 如果您能解决您的问题,请告诉我,如果不能,我会再次检查。

以上是关于删除 Spring RepositoryRestResource 中的“_embedded”属性的主要内容,如果未能解决你的问题,请参考以下文章

Spring / Hibernate - 删除实体时抛出 StaleStateException

在 Spring JPA 中删除实体

Spring:如何从联结表中删除条目?

Spring Batch 支持数据表删除和修改操作吗。

Spring数据elasticsearch批量索引和删除

Spring中单元测试如何插入记录(无删除方法)