You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring GET请求传递Pageable参数反序列化异常解决方案

问题根因

抛出类型转换异常的核心原因有两点:

  • 你错误地将整个Pageable实例作为独立查询参数拼入URL,RestTemplate做URI变量替换时,会直接调用toString()方法将Pageable对象转为字符串,而服务端默认没有提供字符串到Pageable类型的转换器,自然无法完成参数绑定。
  • 你手写的sort参数拼接逻辑不符合Spring Data的参数约定:多字段排序场景下,需要传递多个同名sort参数,而非将所有排序字段、方向拼接为单个sort参数值,单值拼接的写法遇到多字段排序时会直接解析失败。
正确实现方案

服务端接口调整

Spring Data Web模块自带PageableHandlerMethodArgumentResolver解析器,会自动从请求查询参数中提取分页、排序信息组装为Pageable对象,不需要手动接收page、pageSize、sort参数再自行组装,也不需要额外接收名为pageable的查询参数。
修正后的接口代码如下:

@GetMapping("/")
@PageableAsQueryParam
public ResponseEntity<Page<Result>> getAll(
        @RequestHeader("Authorization") String token,
        // 直接声明Pageable参数即可,框架自动完成解析
        Pageable pageable
) {
    // 业务逻辑
}

注意:Spring Data默认的分页大小参数名为size,如果你要兼容之前用的pageSize参数名,可以在application配置中添加如下配置:

spring.data.web.pageable.size-parameter=pageSize

如果不做该配置,客户端传递的pageSize参数无法被分页解析器识别。

客户端请求代码修正

不要手动拼接URI模板和参数Map,直接使用UriComponentsBuilder构造请求地址,同时修正sort参数的拼接逻辑,每个排序规则单独追加一个sort参数,格式为字段名,排序方向。
首先修正你写的分页参数拼接工具方法:

UriComponentsBuilder withPageable(UriComponentsBuilder builder, Pageable pageable) {
    // 如果服务端配置了size参数名为pageSize,这里把"size"替换为"pageSize"即可
    builder.queryParam("page", pageable.getPageNumber())
           .queryParam("size", pageable.getPageSize());
    if (pageable.getSort().isSorted()) {
        pageable.getSort().forEach(order -> {
            // 每个排序规则单独添加一个sort查询参数
            builder.queryParam("sort", order.getProperty() + "," + order.getDirection());
        });
    }
    return builder;
}

修正后的请求发送逻辑如下,删除多余的pageable查询参数传递:

public ResponseEntity<RestResponsePage<Result>> readDocs(Pageable pageable) {
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.add("Authorization", getToken());

    // 构造带分页、排序参数的完整请求URI
    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(baseAppUrl + "/api/k");
    URI requestUri = withPageable(uriBuilder, pageable).build().encode().toUri();

    HttpEntity<Void> requestEntity = new HttpEntity<>(requestHeaders);

    ResponseEntity<RestResponsePage<Result>> response = restTemplate.exchange(
        requestUri,
        HttpMethod.GET,
        requestEntity,
        new ParameterizedTypeReference<RestResponsePage<Result>>() {}
    );
    return response;
}
补充说明
  • 如果你坚持要在服务端单独接收page、pageSize、sort参数,必须删掉方法签名中@RequestParam("pageable") Pageable pageable这段声明,该参数是触发本次类型转换报错的直接原因,属于完全多余的错误写法。
  • 多字段排序的请求格式示例为:/api/k?page=0&size=10&sort=createTime,desc&sort=id,asc,框架会自动解析为「先按创建时间倒序,再按id正序」的排序规则;如果把多个排序规则拼接为单个sort参数值(比如sort=createTime,desc,id,asc),框架无法正确解析排序逻辑。

内容的提问来源于stack exchange,提问作者tryingHard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:30:59