spring - 使用 Spring Data REST 自定义端点

标签 spring spring-mvc spring-boot spring-data-rest

我有一个使用 Spring Boot 1.5.7、Spring Data REST、Hibernate、Spring JPA、Swagger2 的项目。

我有两个像这样的 bean :

    @Entity
public class TicketBundle extends AbstractEntity {
    private static final long serialVersionUID = 404514926837058071L;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Note> notes = new ArrayList<>();

    .....
    }

    @Entity
public class Note extends AbstractEntity {
    private static final long serialVersionUID = -5062313842902549565L;

    @Lob
    private String text;
    ...
    }

我通过存储库公开我的方法:

@Transactional
@RepositoryRestResource(excerptProjection = TicketBundleProjection.class)
@PreAuthorize("isAuthenticated()")
public interface TicketBundleRepository extends PagingAndSortingRepository<TicketBundle, Long> {
....
}

所以在大摇大摆中,我看到了我感兴趣的端点,需要它从特定的票证包中加载注释集合:

enter image description here

现在,我想覆盖默认的 GET/api/v1/ticketBundles/{id}/notes 并将其替换为我在 TicketBundleRepository 中放入的自定义方法:

@Transactional(readOnly = true)
@RestResource(rel = "ticketBundleNotes", path = "/ticketBundles/{id}/notes")
@RequestMapping(method = RequestMethod.GET, path = "/ticketBundles/{id}/notes")
@Query("SELECT n FROM TicketBundle tb JOIN tb.notes n WHERE tb.id=:id ORDER BY n.createdDate DESC,n.id DESC")
public Page<Note> getNotes(@Param("id") long id, Pageable pageable);

通过这种方式创建查询非常方便,因为我需要使用Pageable并返回一个Page。不幸的是,我现在有两个问题。

第一个问题 该方法映射到端点 /api/v1/ticketBundles/search/ticketBundles/{id}/notes 而不是 /api/v1/ticketBundles/ticketBundles/{id}/notes enter image description here

第二个问题 当我从 swagger 调用该方法时,我收到 HTTP 404:

请求似乎有误。似乎路径变量不被理解:

curl -X GET --header 'Accept: application/json' 'http://localhost:8080/api/v1/ticketBundles/search/ticketBundles/{id}/notes?id=1'

这是服务器的响应:

{
   "timestamp": "2017-10-05T14:00:35.563+0000",
   "status": 404,
   "error": "Not Found",
   "message": "No message available",
   "path": "/api/v1/ticketBundles/search/ticketBundles/%7Bid%7D/notes"
 }

服务器端没有任何错误。

有没有办法覆盖端点 GET/api/v1/ticketBundles/{id}/notes 通过 Repository 公开它而不使用自定义 Controller (使用我会失去管理可分页的设施吗?

此外,我在上面显示的调用中获取 HTTP 404 时做错了什么?

最佳答案

我相信您使用了不正确的注释。您需要使用 @RestController 注释您的类,并在方法上使用 @PathVariable 而不是 @Param。这是一个工作示例,您可能需要根据您的需要进行定制。

@org.springframework.data.rest.webmvc.RepositoryRestController
@org.springframework.web.bind.annotation.RestController
public interface PersonRepository extends org.springframework.data.repository.PagingAndSortingRepository<Person, Long> {

    @org.springframework.web.bind.annotation.GetMapping(path = "/people/{id}")
    Person findById(@org.springframework.web.bind.annotation.PathVariable("id") Long id);

}

关于spring - 使用 Spring Data REST 自定义端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46587861/

相关文章:

java - jpa oneToMany 和 jackson 序列化问题(新手)

java - 如何将 bean 注入(inject) @Controller 类

java - 在Testcontainers中使用自定义DB docker-image

java - 我无法使用Spring MVC 3访问jsp页面

java - 使用 Spring MVC 实现搜索表单

java - 如何将 POJO bean 绑定(bind)到公共(public)标题页

java - 运行我的应用程序时出现错误 "context initialization failed"

java - 来自 DB 的图像不会在 JSP 中显示 : No mapping found for HTTP request

java - Heroku - 致命 : password authentication failed for user <>

spring - 如果我们想控制后端的访问,为什么我们需要 Keycloak 权限/策略/范围?