在弹簧数据休息中覆盖PATCH

时间:2018-02-28 07:57:41

标签: spring-boot spring-data-rest

我想用我自己的控制器覆盖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

1 个答案:

答案 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);
}

}