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

使用RestTemplate和UriComponentsBuilder调用带JSON参数API报错如何解决

问题原因
  • UriComponentsBuilder默认会将URI中的{}识别为URI模板占位符,尝试匹配对应变量值进行替换。你传入的filter参数是JSON格式,包含{"code":"xxx"}结构,框架会把"code"识别为待填充的模板变量名,没有传入对应变量值就会抛出该异常。
  • 你的代码还存在额外错误:RestTemplate.getForObject()方法直接返回响应体对象,不会返回ResponseEntity,此处类型不匹配会触发编译/运行时错误。
解决方案

以下两种修复方式可二选一:

方案1:构造URI时禁用模板解析,直接传递URI对象给RestTemplate

不要将构造好的URI转成String字符串,直接生成URI对象传入RestTemplate,同时构建时禁用模板变量解析:

public Person getPerson(String filter, Optional<Integer> size, 
                         Optional<Integer> page, Optional<String> sort){
        String endpoint = "http://localhost:8081/person";

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(endpoint)
                .queryParam("filter", filter);

        page.ifPresent(p -> builder.queryParam("page", p));
        size.ifPresent(s -> builder.queryParam("size", s));
        sort.ifPresent(s -> builder.queryParam("sort", s));

        // 关键:第二个参数false表示不解析模板占位符,直接生成URI对象
        URI uri = builder.build(false).toUri();

        // 修正方法调用,使用getForEntity获取ResponseEntity
        ResponseEntity<Person> response = restTemplate.getForEntity(uri, Person.class);

        return response.getBody();
}

方案2:提前对JSON参数做URL编码后再传入

先将JSON格式的filter参数做URL编码,再传入queryParam,编码后的JSON不会包含{}字符,就不会触发模板解析逻辑:

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public Person getPerson(String filter, Optional<Integer> size, 
                         Optional<Integer> page, Optional<String> sort){
        String endpoint = "http://localhost:8081/person";

        // 对JSON参数做URL编码
        String encodedFilter = URLEncoder.encode(filter, StandardCharsets.UTF_8);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(endpoint)
                .queryParam("filter", encodedFilter);

        page.ifPresent(p -> builder.queryParam("page", p));
        size.ifPresent(s -> builder.queryParam("size", s));
        sort.ifPresent(s -> builder.queryParam("sort", s));

        String url = builder.build().toUriString();
        ResponseEntity<Person> response = restTemplate.getForEntity(url, Person.class);

        return response.getBody();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:36:02