【问题标题】:Custom Spring MVC HTTP Patch requests with Spring Data Rest functionality具有 Spring Data Rest 功能的自定义 Spring MVC HTTP Patch 请求
【发布时间】:2015-10-22 19:00:00
【问题描述】:

在自定义 Spring MVC 控制器中支持 HTTP PATCH 的最佳实践是什么?特别是在使用 HATEOAS/HAL 时?有没有一种更简单的方法来合并对象,而不必检查请求 json 中是否存在每个字段(或编写和维护 DTO),最好是自动解组资源链接?

我知道 Spring Data Rest 中存在此功能,但是否可以利用此功能在自定义控制器中使用?

【问题讨论】:

标签: spring spring-mvc spring-boot spring-data-rest spring-hateoas


【解决方案1】:

我认为你不能在这里使用 spring-data-rest 功能。

spring-data-rest 在内部使用json-patch 库。基本上我认为工作流程如下:

  • 阅读您的实体
  • 使用 objectMapper 将其转换为 json
  • 应用补丁(这里你需要 json-patch)(我认为你的控制器应该将 JsonPatchOperation 列表作为输入)
  • 将修补的 json 合并到您的实体中

我认为困难的部分是第四点。但是,如果您不必有一个通用的解决方案,它可能会更容易。

如果您想了解 spring-data-rest 的作用,请查看 org.springframework.data.rest.webmvc.config.JsonPatchHandler

编辑

spring-data-rest 中的补丁机制在最新版本中发生了显着变化。最重要的是,它不再使用 json-patch 库,而是从头开始实现 json 补丁支持。

我可以设法在自定义控制器方法中重用主要补丁功能。

下面的sn-p说明了基于spring-data-rest 2.6的方法

        import org.springframework.data.rest.webmvc.IncomingRequest;
        import org.springframework.data.rest.webmvc.json.patch.JsonPatchPatchConverter;
        import org.springframework.data.rest.webmvc.json.patch.Patch;

        //...
        private final ObjectMapper objectMapper;
        //...

        @PatchMapping(consumes = "application/json-patch+json")
        public ResponseEntity<Void> patch(ServletServerHttpRequest request) {
          MyEntity entityToPatch = someRepository.findOne(id)//retrieve current state of your entity/object to patch

          Patch patch = convertRequestToPatch(request);
          patch.apply(entityToPatch, MyEntity.class);

          someRepository.save(entityToPatch);
          //...
        }      

        private Patch convertRequestToPatch(ServletServerHttpRequest request) {  
          try {
            InputStream inputStream =  new IncomingRequest(request).getBody();
            return new JsonPatchPatchConverter(objectMapper).convert(objectMapper.readTree(inputStream));
          } catch (IOException e) {
            throw new UncheckedIOException(e);
          }
        }

【讨论】:

  • 谢谢!是的,我已经挖掘了 SDR 的来源。不过,似乎很多功能都可以从 SDR 本身中解开,以获得更通用的解决方案。它肯定会使手动制作符合 HATEOAS 的自定义控制器更容易。
  • 当我尝试这个时,我在objectMapper.readTree(inputStream) 得到java.io.IOException: Stream closed。知道为什么吗?
猜你喜欢
  • 2016-03-23
  • 1970-01-01
  • 2015-03-07
  • 2018-01-08
  • 2016-03-26
  • 2017-03-22
  • 2018-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多