2017-11-01 3 views
1

Ich verwende einen ResourceProcessor, um zusätzliche Links zu meinem Ressourcenobjekt hinzuzufügen, wenn sie in einer Sammlung aufgelistet oder einzeln abgerufen werden. Wenn ich jedoch eine Projektion (oder ein Auszugsprojekt) auf mein Repository anwende, wird der ResourceProcessor nicht ausgeführt und somit werden meine Links für diese Ressource nicht erstellt. Gibt es eine Möglichkeit, meine benutzerdefinierten Ressourcenverknüpfungen zu einer Ressource hinzuzufügen, unabhängig davon, wie der Ressourceninhalt projiziert wird?Spring Data Rest ResourceProcessor nicht auf Projektionen angewendet

Antwort

1

Ich denke, das Problem Ihren Fall beschreibt: https://jira.spring.io/browse/DATAREST-713

Derzeit Feder-data-Rest keine Funktionalität bieten, Ihr Problem zu lösen.

Wir verwenden ein wenig Abhilfe, die immer noch einen separaten ResourceProcessor für jede Projektion benötigt, aber wir müssen nicht die Verknüpfungslogik duplizieren:

Wir haben eine Basisklasse haben die in der Lage ist, den zugrunde liegenden Entity für eine Projektion zu erhalten und ruft die Entität ResourceProcessor auf und wendet die Links auf die Projektion an. Entity ist eine gemeinsame Schnittstelle für alle unsere JPA-Entitäten - aber ich denke, Sie könnten auch org.springframework.data.domain.Persistable oder org.springframework.hateoas.Identifiable verwenden.

/** 
* Projections need their own resource processors in spring-data-rest. 
* To avoid code duplication the ProjectionResourceProcessor delegates the link creation to 
* the resource processor of the underlying entity. 
* @param <E> entity type the projection is associated with 
* @param <T> the resource type that this ResourceProcessor is for 
*/ 
public class ProjectionResourceProcessor<E extends Entity, T> implements ResourceProcessor<Resource<T>> { 

    private final ResourceProcessor<Resource<E>> entityResourceProcessor; 

    public ProjectionResourceProcessor(ResourceProcessor<Resource<E>> entityResourceProcessor) { 
     this.entityResourceProcessor = entityResourceProcessor; 

    } 

    @SuppressWarnings("unchecked") 
    @Override 
    public Resource<T> process(Resource<T> resource) { 
     if (resource.getContent() instanceof TargetAware) { 
      TargetAware targetAware = (TargetAware) resource.getContent(); 
      if (targetAware != null 
        && targetAware.getTarget() != null 
        && targetAware.getTarget() instanceof Entity) { 
       E target = (E) targetAware.getTarget(); 
       resource.add(entityResourceProcessor.process(new Resource<>(target)).getLinks()); 
      } 
     } 
     return resource; 
    } 

} 

Eine Implementierung eines solchen Ressourcen Prozessor würde wie folgt aussehen:

@Component 
public class MyProjectionResourceProcessor extends ProjectionResourceProcessor<MyEntity, MyProjection> { 

    @Autowired 
    public MyProjectionResourceProcessor(EntityResourceProcessor resourceProcessor) { 
     super(resourceProcessor); 
    } 
} 

Die Implementierung selbst geht nur die ResourceProcessor, der die Entity-Klasse verarbeiten kann und übergibt sie an unsere ProjectionResourceProcessor. Es enthält keine Linkerstellungslogik.

Verwandte Themen