2017-04-15 1 views
1

Je suis en train d'ajouter un lien personnalisé au document racine de mon API, après cette réponse: Custom response for root request int the Spring REST HATEOAS with both RepositoryRestResource-s and regular controllersRest données Spring Ajout d'un lien vers Root - RepositoryLinksResource ne peut pas être jeté à la ressource

Ceci est mon processeur ressource personnalisée:

import org.springframework.data.rest.webmvc.RepositoryLinksResource; 
import org.springframework.hateoas.Link; 
import org.springframework.hateoas.ResourceProcessor; 
import org.springframework.hateoas.mvc.ControllerLinkBuilder; 
import org.springframework.stereotype.Component; 

@Component 
public class CustomRootLinksResourceProcessor implements ResourceProcessor<RepositoryLinksResource> { 

    @Override 
    public RepositoryLinksResource process(RepositoryLinksResource resource) { 
     Link link = ControllerLinkBuilder 
       .linkTo(ControllerLinkBuilder 
         .methodOn(CustomerController.class) 
         .register(null)) 
       .withRel("registerCustomer"); 

     resource.add(link); 

     return resource; 
    } 
} 

Cependant, quand je fais une recherche mon API je reçois l'exception suivante

LOGBACK:19:01:03.425 [http-nio-8080-exec-2] ERROR o.s.d.r.w.RepositoryRestExceptionHandler - org.springframework.data.rest.webmvc.RepositoryLinksResource cannot be cast to org.springframework.hateoas.Resource 
java.lang.ClassCastException: org.springframework.data.rest.webmvc.RepositoryLinksResource cannot be cast to org.springframework.hateoas.Resource 
    at org.springframework.hateoas.mvc.ResourceProcessorInvoker$DefaultProcessorWrapper.invokeProcessor(ResourceProcessorInvoker.java:224) 
    at org.springframework.hateoas.mvc.ResourceProcessorInvoker.invokeProcessorsFor(ResourceProcessorInvoker.java:141) 
    at org.springframework.hateoas.mvc.ResourceProcessorInvoker.invokeProcessorsFor(ResourceProcessorInvoker.java:124) 
    at org.springframework.hateoas.mvc.ResourceProcessorHandlerMethodReturnValueHandler.handleReturnValue(ResourceProcessorHandlerMethodReturnValueHandler.java:113) 
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:132) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 

Je ne suis pas sûr de ce que je fais mal, il re, en vérifiant le code source de ResourceProcessorInvoker, il apparaît qu'il n'y a qu'un cast à ResourceSupport (que RepositoryLinksResource étend, donc ça devrait aller). Est-ce un bug dans le repos des données de printemps ou est-il quelque chose de mal avec mon CustomRootLinksResourceProcessor?

@Override 
    @SuppressWarnings("unchecked") 
    public Object invokeProcessor(Object object) { 
     return ((ResourceProcessor<ResourceSupport>) processor).process((ResourceSupport) object); 
    } 

Répondre

2

Alors je suis entré dans le code DTS dans le débogueur et il se trouve que l'exception a été causée par une invocation d'un autre ResourceProcessor, qui ressemblait à ceci:

@Component 
public class CustomerResourceProcessorWrapper { 
    @Bean 
    public ResourceProcessor<Resource<Customer>> customerResourceProcessor() { 

Je suis encore assez nouveau au printemps de données repos et tout ce qu'il est magique de réflexion, mais en remplaçant la déclaration CustomerResourceProcessorWrapper défectueux par un ResourceProcessor straigt résolu le problème pour moi:

@Component 
public class CustomerResourceProcessor implements ResourceProcessor<Resource<Customer>> { 

    @Override 
    public Resource<Customer> process(Resource<Customer> resource) { 
    ... 

J'aimerais toujours savoir ce qu'est cette chose wrapper et pourquoi cela n'a pas fonctionné ... Le même code en utilisant CustomerResourceProcessorWrapper fonctionne très bien à moins que j'ajoute le CustomRootLinksResourceProcessor.

+1

Je pense que l'implémentation 'ResourceProcessor' ** ne doit pas être lambda ** comme dans [docs] (https://docs.spring.io/spring-data/rest/docs/2.6.9.RELEASE/reference/html/# _ the_resourceprocessor_interface). Cela a résolu pour moi. – Sam