Controlador personalizado Spring Data Rest / Spring Hateoas - PersistentEntityResourceAssembler
Estou tentando adicionar alguma lógica comercial adicional aos pontos de extremidade gerados automaticamente a partir do RepositoryRestResource. Por favor veja o código abaixo:
Recurso:
@RepositoryRestResource(collectionResourceRel="event", path="event")
public interface EventRepository extends PagingAndSortingRepository<Event, Long> {
}
Controlador:
@RepositoryRestController
@RequestMapping(value = "/event")
public class EventController {
@Autowired
private EventRepository eventRepository;
@Autowired
private PagedResourcesAssembler<Event> pagedResourcesAssembler;
@RequestMapping(method = RequestMethod.GET, value = "")
@ResponseBody
public PagedResources<PersistentEntityResource> getEvents(Pageable pageable,
PersistentEntityResourceAssembler persistentEntityResourceAssembler) {
Page<Event> events = eventRepository.findAll(pageable);
return pagedResourcesAssembler.toResource(events, persistentEntityResourceAssembler);
}
}
Analisei os dois artigos seguintes sobre stackoverflow:
Posso fazer um controlador personalizado espelhar a formatação das classes geradas pelo Spring-Data-Rest / Spring-Hateoas?Habilitar serialização HAL no Spring Boot para o método do controlador personalizadoSinto que estou perto, mas o problema que estou enfrentando é o seguinte:
return pagedResourcesAssembler.toResource(events, persistentEntityResourceAssembler);
retorna um erro dizendo:
"The method toResource(Page<Event>, Link) in the type PagedResourcesAssembler<Event> is not applicable
for the arguments (Page<Event>, PersistentEntityResourceAssembler)".
O método toResource possui uma assinatura de método que aceita um ResourceAssembler, mas não sei como implementá-lo corretamente e não consigo encontrar nenhuma documentação sobre o assunto.
Agradecemos antecipadamente, - Brian
Editar
Meu problema foi que pensei em substituir os métodos do controlador criados automaticamente a partir de@RepositoryRestResource
anotação sem precisar criar meu próprio recurso e montador de recursos. Depois de criar o recurso e o assembler de recursos, fui capaz de adicionar minha lógica de negócios ao terminal.
Recurso:
public class EventResource extends ResourceSupport {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Assembler de Recursos:
@Component
public class EventResourceAssembler extends ResourceAssemblerSupport<Event, EventResource> {
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;
}
}
Controlador atualizado:
@RepositoryRestController
@RequestMapping(value = "/event")
public class EventController {
@Autowired
private EventRepository eventRepository;
@Autowired
private EventResourceAssembler eventResourceAssembler;
@Autowired
private PagedResourcesAssembler<Event> pageAssembler;
@RequestMapping(method = RequestMethod.GET, value = "")
@ResponseBody
public PagedResources<EventResource> getEvents(Pageable pageable) {
Page<Event> events = eventRepository.findAll(pageable);
// business logic
return pageAssembler.toResource(events, eventResourceAssembler);
}
}
O que eu não gosto nisso é que parece derrotar o propósito de ter um RepositoryRestResource. A outra abordagem seria usar manipuladores de eventos que seriam chamados antes e / ou após as operações de criação, salvamento e exclusão.
@RepositoryEventHandler(Event.class)
public class EventRepositoryEventHandler {
@HandleBeforeCreate
private void handleEventCreate(Event event) {
System.out.println("1");
}
}
Parece não haver eventos para as operações findAll ou findOne. De qualquer forma, essas duas abordagens parecem resolver meu problema de estender os métodos do controlador gerado automaticamente a partir de RepositoryRestResource.