2017-05-28 141 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; 
     } 
    }; 
}