spring data Page / Pageable不能反序列化,怎么用?

时间:2016-01-25 02:19:50

标签: spring spring-data spring-data-jpa

如果在休息的控制器中使用Page / Pageable,我得到错误,因为它们没有用于反序列化的空构造

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.springframework.data.domain.Page, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
 at [Source: java.io.PushbackInputStream@67635da8; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) ~[jackson-databind-2.6.4.jar:2.6.4]
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:892) ~[jackson-databind-2.6.4.jar:2.6.4]
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:139) ~[jackson-databind-2.6.4.jar:2.6.4]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736) ~[jackson-databind-2.6.4.jar:2.6.4]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2810) ~[jackson-databind-2.6.4.jar:2.6.4]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:221) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
... 30 common frames omitted

2 个答案:

答案 0 :(得分:3)

Pageable实现页面不是杰克逊所期望的纯粹POJO。但是,您可以构建自己的Pageable实现。您将能够将您的实现传递给Spring Data,因为它将尊重Pageable合同。

我遇到了问题并且自己实现了Pageable,所以我的Java Rest Client可以与我的Spring Data Jpa Server交换。

答案 1 :(得分:2)

如果您通过HTTP Body传递参数,则需要使用具体实现。推荐丹尼尔的解决方案。

另一个智能解决方案是使用HandlerMethodArgumentResolver

第1步 - 创建与此

类似的参数处理程序
public class PageableHandler implements HandlerMethodArgumentResolver
{
    @Override
    public boolean supportsParameter(MethodParameter methodParameter)
    {
        return methodParameter.getParameterType().equals(Pageable.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception
    {
        String limit = nativeWebRequest.getParameter("limit");
        int size = toInt(limit, 100);

        String offset = nativeWebRequest.getParameter("offset");
        int page = (toInt(offset, size) / size);
        Sort sort = null;
        String sortStr = nativeWebRequest.getParameter("sort");
        String orderStr = nativeWebRequest.getParameter("order");
        if(sortStr != null && orderStr != null)
        {
            Direction direction = "asc".equalsIgnoreCase(orderStr) ? Direction.ASC : Direction.DESC;
            sort = new Sort(direction, sortStr);
        }        
        return new PageRequest(page, size, sort);
    }

    private int toInt(String value, int defaultValue)
    {
        int resultValue = defaultValue;
        if(value != null)
        {
            try
            {
                resultValue = Integer.parseInt(value);
            }catch(NumberFormatException e)
            {
            }
        }
        return resultValue;
    }

}

第2步 - 在Spring配置上注册处理程序

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {


    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new PageableHandler());
        super.addArgumentResolvers(argumentResolvers);
    }
}

第3步 - 在控制器上使用

@RequestMapping(value = "/api/personne", method = RequestMethod.GET)
public List<Personne> getAllPersonnes(Pageable pageable) {
    return adminService.getAllPersonnes(pageable);
}

第4步 - REST GET示例

http://localhost:8080/api/personne?offset=2&limit=25