2015-11-06 12 views
5

Ich versuche, den auto-generierten Endpunkten aus der RepositoryRestResource zusätzliche Geschäftslogik hinzuzufügen. Bitte beachten Sie den Code unten:Spring Data Rest/Frühjahr Hateoas Custom Controller - PersistentEntityResourceAssembler

Ressource:

@RepositoryRestResource(collectionResourceRel="event", path="event") 
public interface EventRepository extends PagingAndSortingRepository<Event, Long> { 

} 

Controller:

@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); 
    } 
} 

Ich habe auf den beiden folgenden Artikel angesehen Stackoverflow:

Ich fühle mich wie ich in der Nähe bin, aber das Problem, dass ich mit Blick auf bin ist, dass:

return pagedResourcesAssembler.toResource(events, persistentEntityResourceAssembler); 

einen Fehler zurückgibt sagen:

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

Die toResource Methode hat eine Methode Signatur, akzeptiert einen ResourceAssembler, aber ich bin nicht sicher, wie man das richtig umsetzt und ich kann keine Dokumentation zu diesem Thema finden.

Vielen Dank im Voraus, - Brian

bearbeiten

Mein Problem war, dass ich dachte, ich könnte die Controller-Methoden überschreibt, die meine eigene Ressource, ohne von @RepositoryRestResource Annotation automatisch erstellt werden erstellen und Ressourcenassembler. Nach dem Erstellen des Ressourcen- und Ressourcen-Assemblers konnte ich dem Endpunkt meine Geschäftslogik hinzufügen.

Ressource:

public class EventResource extends ResourceSupport { 
    private String name; 

    public String getName() { 
    return name; 
    } 

    public void setName(String name) { 
    this.name = name; 
    } 
} 

Ressource-Assembler:

@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; 
    } 
} 

Aktualisiert Controller:

@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); 
    } 
} 

Das, was ich darüber nicht mag, ist, dass es um den Zweck zu besiegen scheint eine RepositoryRestResource haben. Der andere Ansatz wäre, Event-Handler zu verwenden, die vor und/oder nach den Operationen zum Erstellen, Speichern und Löschen aufgerufen werden.

@RepositoryEventHandler(Event.class) 
public class EventRepositoryEventHandler { 

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

Es scheint keine Ereignisse für die Operationen findAll oder findOne zu geben. Wie auch immer, beide Ansätze scheinen mein Problem zu lösen, die automatisch generierten Controller-Methoden von RepositoryRestResource zu erweitern.

+1

http://stackoverflow.com/questions/21346387/how-to-correctly-use-pagedresourcesassembler-from-spring-data kann weitere Informationen bereitstellen. – Jason

+0

@Jason Dank dieser Verbindung half mir definitiv in die richtige Richtung. – bmclachlin

Antwort

1

Es erfordert einen PagedResourcesAssembler, Spring wird eine für Sie injizieren, wenn Sie fragen.

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

In diesem Fall ist die Ressource Foo.In Ihrem Fall scheint die Ressource, die Sie zurückgeben wollen, eine Event ist. Wenn das so ist, würde ich Ihren Code erwarten etwas aussehen:

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

Sie stellen die ResourceAssembler<Event>, dass der Frühling erzählt, wie Event in eine Resource einzuschalten. Spring fügt die PagedResourcesAssembler<Event> in Ihre Controller-Methode ein, um die Paginierungslinks zu verarbeiten. Kombinieren Sie sie, indem Sie toResource anrufen und die injizierte pageAssembler übergeben.

Das Endergebnis kann einfach als Körper wie oben zurückgegeben werden. Sie könnten auch Dinge wie HttpEntity verwenden, um mehr Kontrolle über Statuscodes und Header zu bekommen.

Hinweis: Die ResourceAssembler, die Sie bereitstellen, kann buchstäblich etwas so einfaches wie das Umschließen der Ressource, wie Event, mit einem Resource Objekt sein. Im Allgemeinen möchten Sie jedoch relevante Links hinzufügen.

+0

Danke für Ihre Antwort. Ich dachte, es wäre vielleicht möglich, die automatisch generierten Endpunkte aus der Annotation RepositoryRestResource zu überschreiben, ohne eine EventResource und einen EventResourceAssembler erstellen zu müssen. Stellen Sie sich die beste Lösung vor, eine Klasse mit der RepositoryEventHandler-Annotation zu verwenden und die Ereignisse zu verwenden, die vom REST-Exportprogramm ausgegeben werden. Auf diese Weise muss ich mein EventRepository nicht berühren und kann meine Geschäftslogik zu diesen Endpunkten hinzufügen. – bmclachlin