2017-05-28 143 views
0

我試圖使用Spring Data Rest資源處理器向鏈接添加資源;然而,在MockMvc集成測試,它吹了一個類轉換異常,抱怨的EmptyCollectionEmbeddedWrapper不能轉換到ResourceSupport(在ResourceProcessor的參數化類型的邊界):Spring Data Rest資源處理失敗

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] 

它的預期,返回值在這一點上應該是空的(如EmptyCollectionEmbeddedWrapper建議),但是當然不會有類別轉換。如堆棧跟蹤所示,此異常發生在資源後期處理期間;如果我刪除了這個類型的簡單資源處理器,類拋出異常消失並且請求成功。這對我來說是令人驚訝的,因爲資源處理器基本上從文檔中解除了。

更詳細地說,資源參數類型是Notification;該MockMvc請求失敗的樣子:

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

而且ResourceProcessor樣子:

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

我想我已經得到的東西錯誤配置,因爲這似乎是春天數據休息的一個非常基本的用法。我錯過了什麼?

回答

1

在ResourceProcessorInvoker調試後發現,對於ResourceProcessor解析的類型不ResourceProcessor<Resource<T>>(在你的情況ResourceProcessor<Resource<Notification>>)如預期,但ResourceProcessor<T extends ResourceSupport>>。原因是使用lambda創建處理器。 以舊的方式創建匿名類解決了我的情況下的問題:

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