无法实例化 Pageable bean
Posted
技术标签:
【中文标题】无法实例化 Pageable bean【英文标题】:Failed to instantiate Pageable bean 【发布时间】:2015-07-15 10:34:04 【问题描述】:我使用 Spring 4.1.6.RELEASE 和 Spring Data Jpa 1.8.0.RELEASE。我在创建 org.springframework.data.domain.Pageable bean 时遇到问题。 它在我的控制器中使用:
@Controller
public class ItemsController
@Autowired
ProductService itemsService;
@RequestMapping(value = "/openItemsPage")
public String openItemsPage()
return "items";
@RequestMapping(value = "/getItems", method = RequestMethod.GET)
@ResponseBody
public Item[] getItems(Pageable pageable)
return itemsService.getItems(pageable);
我的应用程序上下文中还有下一个 xml 配置:
<context:component-scan base-package="com.mobox.controller" />
<mvc:annotation-driven>
<mvc:argument-resolvers>
<beans:bean id="sortResolver"
class="org.springframework.data.web.SortHandlerMethodArgumentResolver" />
<beans:bean
class="org.springframework.data.web.PageableHandlerMethodArgumentResolver">
<beans:constructor-arg ref="sortResolver" />
</beans:bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
最后我从客户那里做一个下一个请求:
$.ajax(
type: "GET",
url: "getProducts?page=0&size=100",
.....
在tomcat日志中我看到下一个:
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/a2delivery-web] threw exception [Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.domain.Pageable]: Specified class is an interface] with root cause
org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.domain.Pageable]: Specified class is an interface
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:80)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:106)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
....................
请帮我解决这个问题,谢谢!
【问题讨论】:
能把控制器的完整源码贴出来吗? 当然,更新了控制器描述 【参考方案1】:最简单的方法是在你的配置中设置@EnableSpringDataWebSupport
。或者,在基于纯 XML 的配置中,将 SpringDataWebConfiguration
声明为 Spring bean。
这将确保正确注册必要的HandlerMethodArgumentResolver
。
【讨论】:
谢谢,看来你是对的,但钢铁问题是实际存在的。在堆栈跟踪中,我看到 HandlerMethodArgumentResolverComposite 类正在完成一项工作:对于具有“parametrType”的实际 MethodParameter 参数 org.springframework.data.domain.Pageable 它应该获得 PageableHandlerMethodArgumentResolver,但在我的情况下它正在获得 org.springframework.web.servlet.mvc .method.annotation.ServletModelAttributeMethodProcessor,为什么? 好像你的 Spring MVC 配置自定义没有应用。 在全部配置为基于 java 的配置时工作,但是当我混合 xml 和基于 java 的配置时 - 不是。对于 xml 配置,下一个解决方案有效:***.com/questions/22135002/… @EnableSpringDataWebSupport 引入了一个扩展 WebMvcConfigurerAdapter 的新配置类。它可能会覆盖您的配置 - 反之亦然。 在@WebMvcTest
中遇到了这个问题。将@EnableSpringDataWebSupport
添加到我的内部@TestConfiguration
类中解决了它。【参考方案2】:
将以下内容添加到您的测试类中:
@Inject
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
PageableHandlerMethodArgumentResolver
并在 MockMvc 设置期间对其进行配置:
@Before
public void setup()
...
this.mockMvc = MockMvcBuilders.standaloneSetup(resource)
.setCustomArgumentResolvers(pageableArgumentResolver)
.build();
【讨论】:
在我的情况下,如果没有 @EnableSpringDataWebSupport 它将无法工作。 我的项目没有 @Inject 但我可以新建一个 PageableHandlerMethodArgumentResolver 来帮助修复它。【参考方案3】:只是为了补充Tom Van Rossom的回复,如果你使用@RunWith(MockitoJUnitRunner.class),你可以在初始化mockMvc时创建一个PageableHandlerMethodArgumentResolver的实例(就像Loren提到的那样)。例如
mockMvc = MockMvcBuilders.standaloneSetup(restController)
.setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
.build();
【讨论】:
【参考方案4】:除了其他可能对您有用的答案之外的替代方法。
@Configuration
@ComponentScan(basePackages = "my.package1", "my.package2")
@EnableWebMvc
public class SpringMVCRestConfiguration extends WebMvcConfigurerAdapter
//Adding the resolver for Pagination and Sorting Resolver
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers)
argumentResolvers.add(paginationResolver());
argumentResolvers.add(sortResolver());
//Inject the sortResolver
@Bean
public SortHandlerMethodArgumentResolver sortResolver()
SortHandlerMethodArgumentResolver argumentResolver = new SortHandlerMethodArgumentResolver();
return argumentResolver;
//Inject the Pagination Resolver
@Bean
public PageableHandlerMethodArgumentResolver paginationResolver()
PageableHandlerMethodArgumentResolver argumentResolver = new PageableHandlerMethodArgumentResolver();
argumentResolver.setMaxPageSize(10);
argumentResolver.setOneIndexedParameters(true);
return argumentResolver;
【讨论】:
【参考方案5】:getItems 方法中使用的 Pageable 是一个接口,spring 将无法实例化它。
你可以
-
提供一个 Java bean 样式的 Pageable 实现,并在 getItems 方法中使用它而不是 Pageable。
或者使用ModelAttribute创建一个Pageable对象(例如PageRequest)。这是有关 ModelAttribute 的更多详细信息的链接:What is @ModelAttribute in Spring MVC?
【讨论】:
以上是关于无法实例化 Pageable bean的主要内容,如果未能解决你的问题,请参考以下文章