处理自定义 POST PUT 中的关联条目和 spring 数据中的 PATCH 请求
Handling association entries in custom POST PUT and PATCH requests in spring data rest
我有一个要求,其中我必须在 POST、PATCH 和 PUT 端点中具有自定义业务逻辑。使用 SDR 事件是不可能的,因为我需要在请求中执行几个事务操作。因此,我决定为通过服务 class.
附加到存储库的实体创建自定义端点
@RepositoryRestController
@RequestMapping("/myEntity")
@ExposesResourceFor(MyEntity.class)
public class MyEntityResource {
@PostMapping(value = "", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity postResult(@RequestBody Entity entity) {
// my logic
}
}
现在我面临一个问题,即我的 POST 请求可能具有指向其他实体的关联链接。 SDR 的默认实现可以优雅地处理这个问题,但我遇到了 Jackson 映射错误。
JSON parse error: Cannot construct instance of `com.foo.bar.Entity` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('/api/v1/entity/12345678-1234-1234-1234-123456789012')
于是我查看了Spring的实现方式,发现了下面的方法
@ResponseBody
@RequestMapping(value = BASE_MAPPING, method = RequestMethod.POST)
public ResponseEntity<ResourceSupport> postCollectionResource(RootResourceInformation resourceInformation,
PersistentEntityResource payload, PersistentEntityResourceAssembler assembler,
@RequestHeader(value = ACCEPT_HEADER, required = false) String acceptHeader)
并且我发现 PersistentEntityResource payload
填充了获取的关联实体,并且主要实体通过对存储库的正常保存调用保存。
所以,我尝试了自动装配 PersistentEntityResource
,但这基本上失败了,因为 PersistentEntityResource
的调用者期望映射 url 的形式是 /{repository}/<optional id>
,正如我已经知道我的路径是什么,PersistentEntityResource
无法初始化。 PersistentEntityResource
不是通用的也无济于事(直到 SDR 2.0.0.M1 才被删除)。另外,如果能够使用 PersistentEntityResource
,那么实施 PATCH 和 PUT 也会变得更加容易。
有什么办法可以解决这个问题吗?
经过一番挖掘,我找到了答案。事后看来,这是非常微不足道的。只需在方法参数中使用 Resource<Entity>
而不是 Entity
。
@RepositoryRestController
@RequestMapping("/myEntity")
@ExposesResourceFor(MyEntity.class)
public class MyEntityResource {
@PostMapping(value = "", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity postResult(@RequestBody Resource<Entity> entity) {
// my logic. Fetch the entity with entity.getContent()
}
}
您可以使用 entity.getContent()
获取实体本身
我有一个要求,其中我必须在 POST、PATCH 和 PUT 端点中具有自定义业务逻辑。使用 SDR 事件是不可能的,因为我需要在请求中执行几个事务操作。因此,我决定为通过服务 class.
附加到存储库的实体创建自定义端点@RepositoryRestController
@RequestMapping("/myEntity")
@ExposesResourceFor(MyEntity.class)
public class MyEntityResource {
@PostMapping(value = "", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity postResult(@RequestBody Entity entity) {
// my logic
}
}
现在我面临一个问题,即我的 POST 请求可能具有指向其他实体的关联链接。 SDR 的默认实现可以优雅地处理这个问题,但我遇到了 Jackson 映射错误。
JSON parse error: Cannot construct instance of `com.foo.bar.Entity` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('/api/v1/entity/12345678-1234-1234-1234-123456789012')
于是我查看了Spring的实现方式,发现了下面的方法
@ResponseBody
@RequestMapping(value = BASE_MAPPING, method = RequestMethod.POST)
public ResponseEntity<ResourceSupport> postCollectionResource(RootResourceInformation resourceInformation,
PersistentEntityResource payload, PersistentEntityResourceAssembler assembler,
@RequestHeader(value = ACCEPT_HEADER, required = false) String acceptHeader)
并且我发现 PersistentEntityResource payload
填充了获取的关联实体,并且主要实体通过对存储库的正常保存调用保存。
所以,我尝试了自动装配 PersistentEntityResource
,但这基本上失败了,因为 PersistentEntityResource
的调用者期望映射 url 的形式是 /{repository}/<optional id>
,正如我已经知道我的路径是什么,PersistentEntityResource
无法初始化。 PersistentEntityResource
不是通用的也无济于事(直到 SDR 2.0.0.M1 才被删除)。另外,如果能够使用 PersistentEntityResource
,那么实施 PATCH 和 PUT 也会变得更加容易。
有什么办法可以解决这个问题吗?
经过一番挖掘,我找到了答案。事后看来,这是非常微不足道的。只需在方法参数中使用 Resource<Entity>
而不是 Entity
。
@RepositoryRestController
@RequestMapping("/myEntity")
@ExposesResourceFor(MyEntity.class)
public class MyEntityResource {
@PostMapping(value = "", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity postResult(@RequestBody Resource<Entity> entity) {
// my logic. Fetch the entity with entity.getContent()
}
}
您可以使用 entity.getContent()