无法实例化 Pageable bean

Failed to instantiate Pageable bean

我使用 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)
    ....................

请帮我解决这个问题,谢谢!

getItems 方法中使用的 Pageable 是一个接口,spring 将无法实例化它。

您可以

  1. 提供 Pageable 的 Java bean 样式实现,并在 getItems 方法中使用它代替 Pageable。
  2. 或者使用 ModelAttribute 创建一个 Pageable 对象(例如 PageRequest)。这是有关 ModelAttribute 的更多详细信息的 link:What is @ModelAttribute in Spring MVC?

实现此功能的最简单方法是在您的配置中设置 @EnableSpringDataWebSupport。或者,在基于纯 XML 的配置中,将 SpringDataWebConfiguration 声明为 Spring bean。

这将确保正确注册必要的 HandlerMethodArgumentResolver

将以下内容添加到您的测试中 class:

@Inject
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;

PageableHandlerMethodArgumentResolver

并在 MockMvc 设置期间配置它:

@Before
public void setup() {
    ...
    this.mockMvc = MockMvcBuilders.standaloneSetup(resource)
        .setCustomArgumentResolvers(pageableArgumentResolver)
        .build();
}

只是为了补充 Tom Van Rossom 的回复,如果你使用 @RunWith(MockitoJUnitRunner.class),你可以在初始化 mockMvc 时创建一个 PageableHandlerMethodArgumentResolver 的实例(就像 Loren 提到的那样)。例如

mockMvc = MockMvcBuilders.standaloneSetup(restController)
            .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
            .build();

除了可能对您有用的其他答案之外的替代方法。

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