我想用我自己的控制器覆盖spring-data-rest中资源的PATCH方法。我目前有这个:
@RepositoryRestResource
interface ItemRepository extends JpaRepository<Item, Long> {
}
@RepositoryRestController
@Slf4j
class ItemController {
@Autowired
private ItemRepository itemRepository;
@PatchMapping("/items/{id}")
public void updateItem(@PathVariable("id") Long id, @RequestBody ItemDTO itemDTO) {
log.info("Updating item {}", id);
Item found = itemRepository.findOne(id);
found.name = itemDTO.name;
itemRepository.save(found);
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class ItemDTO {
String name;
}
我可以通过调用创建一个项目:
curl -X POST \
http://localhost:8080/items \
-H 'Content-Type: application/json' \
-d '{
"name" : "anItem"
}'
但是,如果我尝试使用PATCH
更新项目,请执行以下操作:
curl -X PATCH \
http://localhost:8080/items/1 \
-H 'Content-Type: application/json' \
-d '{
"name" : "update"
}'
请求由我自己的控制器处理,但应用程序也会抛出此堆栈跟踪并以状态代码400响应。
2018-02-27 16:58:55.510 ERROR 16112 --- [o-auto-1-exec-1] o.s.d.r.w.RepositoryRestExceptionHandler : I/O error while reading input message; nested exception is java.io.IOException: Stream closed
org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:229) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:150) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:128) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
我在这里创建了一个示例项目(带有演示错误的测试):https://github.com/JanRenkin/springdatarest
答案 0 :(得分:0)
使用@BasePathAwareController 注释,您可以覆盖弹簧数据休息路径的默认实现。为避免发生错误,您的方法应返回该实体。
@BasePathAwareController
@Slf4j
class ItemController {
@Autowired
private ItemRepository itemRepository;
@PatchMapping("/items/{id}")
public ResponseEntity<Item> updateItem(@PathVariable("id") Long id, @RequestBody
ItemDTO itemDTO) {
log.info("Updating item {}", id);
Item found = itemRepository.findOne(id);
found.name = itemDTO.name;
Item savedItem =itemRepository.save(found);
return new ResponseEntity<>(savedItem , HttpStatus.OK);
}
}