2017-05-28 6 views
0

Ich versuche Spring Resource Resource-Prozessoren zu verwenden, um eine Verknüpfung zu einer Ressource hinzuzufügen; Jedoch während MockMvc Integrationstests, bläst sie mit einer Klasse Guss Ausnahme auf, beschwert, dass eine EmptyCollectionEmbeddedWrapper nicht auf ResourceSupport (die Grenzen des ResourceProcessor ‚s parametrisierten Typ) umgewandelt werden:Spring Data Rest Ressourcenverarbeitungsfehler

java.lang.ClassCastException: org.springframework.hateoas.core.EmbeddedWrappers$EmptyCollectionEmbeddedWrapper cannot be cast to org.springframework.hateoas.ResourceSupport 
    at org.springframework.data.rest.webmvc.ResourceProcessorInvoker$DefaultProcessorWrapper.invokeProcessor(ResourceProcessorInvoker.java:225) ~[spring-data-rest-webmvc-2.5.3.RELEASE.jar:na] 
    at org.springframework.data.rest.webmvc.ResourceProcessorInvoker.invokeProcessorsFor(ResourceProcessorInvoker.java:142) ~[spring-data-rest-webmvc-2.5.3.RELEASE.jar:na] 
    at org.springframework.data.rest.webmvc.ResourceProcessorInvoker.invokeProcessorsFor(ResourceProcessorInvoker.java:119) ~[spring-data-rest-webmvc-2.5.3.RELEASE.jar:na] 
    at org.springframework.data.rest.webmvc.ResourceProcessorHandlerMethodReturnValueHandler.handleReturnValue(ResourceProcessorHandlerMethodReturnValueHandler.java:114) ~[spring-data-rest-webmvc-2.5.3.RELEASE.jar:na] 
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:130) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.5.5.jar:8.5.5] 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.5.5.jar:8.5.5] 
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE] 

es, dass der zurückgegebene Wert erwartet wird sollte an dieser Stelle leer sein (wie EmptyCollectionEmbeddedWrapper vorschlägt), aber natürlich ist die Klassenbesetzung nicht beabsichtigt. Wie der Stack-Trace vermuten lässt, tritt diese Ausnahme während der Ressourcen-Nachverarbeitung auf. Wenn ich einen einfachen Ressourcenprozessor für diesen Typ entferne, verschwindet die Klassenausnahme und die Anfrage ist erfolgreich. Dies ist für mich überraschend, da der Ressourcenprozessor im Wesentlichen aus der Dokumentation entfernt ist.

Ausführlicher ist der Ressourcenparametertyp Notification; die MockMvc Anforderung, die nicht aussieht:

perform(get(entityLinks.linkToSearchResource(Notification.class, NotificationRepository.ACTIVE_SEARCH) 
      .expand(Collections.singletonMap("projectId", 1)).getHref())) 
      .andExpect(status().isOk()) 
      .andExpect(jsonPath("$._embedded.notifications").isEmpty()); 

Und die ResourceProcessor wie folgt aussieht:

@Bean 
public ResourceProcessor<Resource<Notification>> notificationResourceProcessor(RepositoryEntityLinks entityLinks) { 
    return notificationResource -> { 
     notificationResource.add(entityLinks.linkToCollectionResource(NotificationAction.class)); 
     return notificationResource; 
    }; 
} 

Ich nehme ich etwas falsch konfiguriert haben, weil dies wie eine sehr grundlegende Verwendung von Spring Data Erholung scheint. Was vermisse ich?

Antwort

1

Nach Debuggen in ResourceProcessorInvoker festgestellt, dass der aufgelösten Typ für die ResourceProcessor nicht ResourceProcessor<Resource<T>> war (in Ihrem Fall ResourceProcessor<Resource<Notification>>) wie erwartet, aber ResourceProcessor<T extends ResourceSupport>>. Der Grund ist die Erstellung des Prozessors mit Lambda. Erstellen der anonymen Klasse in der alten Art und Weise löste das Problem in meinem Fall:

@Bean 
public ResourceProcessor<Resource<Notification>> notificationResourceProcessor(RepositoryEntityLinks entityLinks) { 
    return new ResourceProcessor<Resource<Notification>>() { 
     @Override 
     public Resource<Notification> process(Resource<Notification> notificationResource) { 
      notificationResource.add(entityLinks.linkToCollectionResource(NotificationAction.class)); 
      return notificationResource; 
     } 
    }; 
} 
Verwandte Themen