具有 Spring Data Rest 功能的自定义 Spring MVC HTTP 补丁请求
Custom Spring MVC HTTP Patch requests with Spring Data Rest functionality
在自定义 Spring MVC 控制器中支持 HTTP PATCH 的最佳实践是什么?特别是在使用 HATEOAS/HAL 时?有没有更简单的方法来合并对象,而不必检查请求中每个字段的存在 json(或编写和维护 DTO),最好是自动解组资源链接?
我知道 Spring Data Rest 中存在此功能,但是否可以利用此功能在自定义控制器中使用?
我认为您不能在此处使用 spring-data-rest 功能。
spring-data-rest 在内部使用 json-patch 库。基本上我认为工作流程如下:
- 阅读您的实体
- 使用 objectMapper
将其转换为 json
- 应用补丁(这里你需要 json-补丁)(我认为你的控制器应该将 JsonPatchOperation 列表作为输入)
- 将补丁 json 合并到您的实体中
我觉得比较难的是第四点。但是,如果您不必拥有通用解决方案,它可能会更容易。
如果您想了解 spring-data-rest 的作用 - 请查看 org.springframework.data.rest.webmvc.config.JsonPatchHandler
编辑
spring-data-rest 中的补丁机制在最新版本中发生了重大变化。最重要的是,它不再使用 json-patch 库,现在正在从头开始实现 json 补丁支持。
我可以设法在自定义控制器方法中重用主要补丁功能。
以下代码片段说明了基于 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);
}
}
在自定义 Spring MVC 控制器中支持 HTTP PATCH 的最佳实践是什么?特别是在使用 HATEOAS/HAL 时?有没有更简单的方法来合并对象,而不必检查请求中每个字段的存在 json(或编写和维护 DTO),最好是自动解组资源链接?
我知道 Spring Data Rest 中存在此功能,但是否可以利用此功能在自定义控制器中使用?
我认为您不能在此处使用 spring-data-rest 功能。
spring-data-rest 在内部使用 json-patch 库。基本上我认为工作流程如下:
- 阅读您的实体
- 使用 objectMapper 将其转换为 json
- 应用补丁(这里你需要 json-补丁)(我认为你的控制器应该将 JsonPatchOperation 列表作为输入)
- 将补丁 json 合并到您的实体中
我觉得比较难的是第四点。但是,如果您不必拥有通用解决方案,它可能会更容易。
如果您想了解 spring-data-rest 的作用 - 请查看 org.springframework.data.rest.webmvc.config.JsonPatchHandler
编辑
spring-data-rest 中的补丁机制在最新版本中发生了重大变化。最重要的是,它不再使用 json-patch 库,现在正在从头开始实现 json 补丁支持。
我可以设法在自定义控制器方法中重用主要补丁功能。
以下代码片段说明了基于 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);
}
}