将自定义 header 添加到 REST PUT 请求
Add custom header to REST PUT request
我有一个使用 Spring Boot 2.1.8 和 Angular 前端的应用程序。我已经使用@RepositoryRestResource 定义了我的存储库。 Spring Boot 应用程序基本上为 Angular 片段提供了一个 REST API。该应用程序定义了多个业务实体,REST respo 为每个实体提供了 CRUD 功能。这是其中一个实体的典型回购接口:
// REST resouce /api/privgroups
@RepositoryRestResource(collectionResourceRel = "privgroups", path = "privgroups")
public interface PrivGroupRepository extends CrudRepository<PrivGroup, Long>
{
List<PrivGroup> findAll();
}
GETing 和单个实体、POSTing(创建实体)和 PUTing(更新实体)都工作正常,但我想 return 自定义 header 更新时(HTTP PUT ) 一个实体。 header 将由 Angular 端使用,以显示特定于该实体的自定义 toastr 消息。由于存储库还实现了 REST 接口,我不确定如何添加一个特定的 header,它会根据目标实体而改变。
我开发的应用程序包含一个 REST 控制器,该控制器调用一个服务,而该服务又调用一个存储库。在这种情况下,我有更多的控制权,可以轻松地 return 自定义 header,如下所示:
@PutMapping("/{id}")
public ResponseEntity<MyEntity> updateMyEntity(@PathVariable("id") Long id, @RequestBody MyEntity myEntity)
{
MyEntity updatedEntity = this.MyEntityService.updateMyEntity(MyEntity);
return ResponseEntity.ok()
.header("X-Save", "MyEntity")
.body(updatedEntity);
}
我可以使用更新的 "built-in" 技术来实现这一目标吗?我知道我可以使用过滤器添加 headers,并且我已经阅读了一些关于该主题的 posts。我认为很难确定正在更新的实体,我不确定这是最好的方法。
请注意 post:
Rest API - how add custom headers?
真的很老。
spring 数据其余文档 https://docs.spring.io/spring-data/rest/docs/current/reference/html/
没有关于该主题的任何具体信息。
我最近使用了 Spring Data Rest,但我没有找到任何 "built-in" 技术。但是,您可以通过在带有 @ 注释的 class 中实现 ResponseBodyAdvice 接口来实现这一点控制器建议。我是这样得到它的:
@ControllerAdvice
public class PutMyEntityBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// Write the condition to check if beforyBodyWrite should be called
return returnType.getParameterType().equals(ResponseEntity.class);
}
@Override
public Object beforeBodyWrite(Object object, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
// Check if it is a PUT request for MyEntity object
if (HttpMethod.PUT.equals(request.getMethod()) && object instanceof PersistentEntityResource) {
PersistentEntityResource persistentEntityResource = (PersistentEntityResource) object;
if (persistentEntityResource.getContent().getClass().equals(MyEntity.class)) {
// Add custom header or manipulate response object
response.getHeaders().add("X-Save", "MyEntity");
}
}
return object;
}
}
@pepevalbe 的回答看起来很有希望。
如您所建议的,替代方案可能是使用标准 Servlet 过滤器或 Spring HandlerInterceptor。
为了解决在这种情况下获取对修改实体的引用的问题,您可以注册一个 Spring Data Rest 事件侦听器,它可以简单地将对修改实体的引用存储在 ThreadLocal 存储中,从那里它可以在 Filter 或 HandlerInterceptor 中检索。
https://www.baeldung.com/java-threadlocal
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#events.application-listener
我有一个使用 Spring Boot 2.1.8 和 Angular 前端的应用程序。我已经使用@RepositoryRestResource 定义了我的存储库。 Spring Boot 应用程序基本上为 Angular 片段提供了一个 REST API。该应用程序定义了多个业务实体,REST respo 为每个实体提供了 CRUD 功能。这是其中一个实体的典型回购接口:
// REST resouce /api/privgroups
@RepositoryRestResource(collectionResourceRel = "privgroups", path = "privgroups")
public interface PrivGroupRepository extends CrudRepository<PrivGroup, Long>
{
List<PrivGroup> findAll();
}
GETing 和单个实体、POSTing(创建实体)和 PUTing(更新实体)都工作正常,但我想 return 自定义 header 更新时(HTTP PUT ) 一个实体。 header 将由 Angular 端使用,以显示特定于该实体的自定义 toastr 消息。由于存储库还实现了 REST 接口,我不确定如何添加一个特定的 header,它会根据目标实体而改变。
我开发的应用程序包含一个 REST 控制器,该控制器调用一个服务,而该服务又调用一个存储库。在这种情况下,我有更多的控制权,可以轻松地 return 自定义 header,如下所示:
@PutMapping("/{id}")
public ResponseEntity<MyEntity> updateMyEntity(@PathVariable("id") Long id, @RequestBody MyEntity myEntity)
{
MyEntity updatedEntity = this.MyEntityService.updateMyEntity(MyEntity);
return ResponseEntity.ok()
.header("X-Save", "MyEntity")
.body(updatedEntity);
}
我可以使用更新的 "built-in" 技术来实现这一目标吗?我知道我可以使用过滤器添加 headers,并且我已经阅读了一些关于该主题的 posts。我认为很难确定正在更新的实体,我不确定这是最好的方法。
请注意 post: Rest API - how add custom headers? 真的很老。 spring 数据其余文档 https://docs.spring.io/spring-data/rest/docs/current/reference/html/ 没有关于该主题的任何具体信息。
我最近使用了 Spring Data Rest,但我没有找到任何 "built-in" 技术。但是,您可以通过在带有 @ 注释的 class 中实现 ResponseBodyAdvice 接口来实现这一点控制器建议。我是这样得到它的:
@ControllerAdvice
public class PutMyEntityBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// Write the condition to check if beforyBodyWrite should be called
return returnType.getParameterType().equals(ResponseEntity.class);
}
@Override
public Object beforeBodyWrite(Object object, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
// Check if it is a PUT request for MyEntity object
if (HttpMethod.PUT.equals(request.getMethod()) && object instanceof PersistentEntityResource) {
PersistentEntityResource persistentEntityResource = (PersistentEntityResource) object;
if (persistentEntityResource.getContent().getClass().equals(MyEntity.class)) {
// Add custom header or manipulate response object
response.getHeaders().add("X-Save", "MyEntity");
}
}
return object;
}
}
@pepevalbe 的回答看起来很有希望。
如您所建议的,替代方案可能是使用标准 Servlet 过滤器或 Spring HandlerInterceptor。
为了解决在这种情况下获取对修改实体的引用的问题,您可以注册一个 Spring Data Rest 事件侦听器,它可以简单地将对修改实体的引用存储在 ThreadLocal 存储中,从那里它可以在 Filter 或 HandlerInterceptor 中检索。
https://www.baeldung.com/java-threadlocal
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#events.application-listener