Spring Data Rest / Spring Hateoas自定义控制器 – PersistentEntityResourceAssembler

我正在尝试从RepositoryRestResource向自动生成的端点添加一些额外的业务逻辑。 请参阅以下代码:

资源:

@RepositoryRestResource(collectionResourceRel="event", path="event") public interface EventRepository extends PagingAndSortingRepository { } 

控制器:

 @RepositoryRestController @RequestMapping(value = "/event") public class EventController { @Autowired private EventRepository eventRepository; @Autowired private PagedResourcesAssembler pagedResourcesAssembler; @RequestMapping(method = RequestMethod.GET, value = "") @ResponseBody public PagedResources getEvents(Pageable pageable, PersistentEntityResourceAssembler persistentEntityResourceAssembler) { Page events = eventRepository.findAll(pageable); return pagedResourcesAssembler.toResource(events, persistentEntityResourceAssembler); } } 

我查看了以下两篇stackoverflow文章:

  • 我可以为自定义控制器镜像生成Spring-Data-Rest / Spring-Hateoas生成的类的格式吗?
  • 在Spring Boot中启用HAL序列化以获取自定义控制器方法

我觉得我很亲密,但我面临的问题是:

 return pagedResourcesAssembler.toResource(events, persistentEntityResourceAssembler); 

返回错误说:

 "The method toResource(Page, Link) in the type PagedResourcesAssembler is not applicable for the arguments (Page, PersistentEntityResourceAssembler)". 

toResource方法有一个接受ResourceAssembler的方法签名,但我不确定如何正确实现它,我找不到任何关于此事的文档。

提前谢谢, – 布莱恩

编辑

我的问题是我认为我可以覆盖从@RepositoryRestResource注释自动创建的控制器方法,而无需创建自己的资源和资源汇编程序。 创建资源和资源汇编程序后,我能够将业务逻辑添加到端点。

资源:

 public class EventResource extends ResourceSupport { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } 

资源汇编程序:

 @Component public class EventResourceAssembler extends ResourceAssemblerSupport { public EventResourceAssembler() { super(EventController.class, EventResource.class); } @Override public EventResource toResource(Event entity) { EventResource eventResource = createResourceWithId(entity.getId(), entity); eventResource.setName(entity.getName()); return eventResource; } } 

更新控制器:

 @RepositoryRestController @RequestMapping(value = "/event") public class EventController { @Autowired private EventRepository eventRepository; @Autowired private EventResourceAssembler eventResourceAssembler; @Autowired private PagedResourcesAssembler pageAssembler; @RequestMapping(method = RequestMethod.GET, value = "") @ResponseBody public PagedResources getEvents(Pageable pageable) { Page events = eventRepository.findAll(pageable); // business logic return pageAssembler.toResource(events, eventResourceAssembler); } } 

我不喜欢这件事,它似乎打败了拥有RepositoryRestResource的目的。 另一种方法是使用在创建,保存,删除操作之前和/或之后调用的事件处理程序。

 @RepositoryEventHandler(Event.class) public class EventRepositoryEventHandler { @HandleBeforeCreate private void handleEventCreate(Event event) { System.out.println("1"); } } 

findAll或findOne操作似乎没有任何事件。 无论如何,这两种方法似乎都解决了我从RepositoryRestResource扩展自动生成的控制器方法的问题。

它需要一个PagedResourcesAssembler,如果你问,Spring会为你注入一个。

 public PagedResources get(Pageable page, PagedResourcesAssembler assembler) { // ... } 

在这种情况下,资源是Foo 。 在您的情况下,您尝试返回的资源似乎是一个Event 。 如果是这样,我希望您的代码看起来像:

 private ResourceAssembler eventAssembler = ...; public PagedResources get(Pageable page, PagedResourcesAssembler pageAssembler) { Event event = ...; return eventAssembler.toResource(event, pageAssembler); } 

您提供了ResourceAssembler ,它告诉Spring如何将Event转换为Resource 。 Spring将PagedResourcesAssembler注入到控制器方法中以处理分页链接。 通过调用toResource并传入注入的pageAssembler组合它们。

最终结果可以像上面一样简单地返回。 您还可以使用HttpEntity类的HttpEntity来获得对状态代码和标题的更多控制。

注意:您提供的ResourceAssembler实际上可以像使用Resource对象包装资源(如Event一样简单。 通常,您会想要添加任何相关链接。