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

Spring中如何对含对象参数的请求URL进行正确编码?

解决RestTemplate传递JSON作为GET请求参数的URL编码问题

你遇到的核心问题是URL中的JSON字符串没有正确编码,导致UriBuilder解析失败。Postman会自动帮你处理URL编码,所以能正常工作,但RestTemplate不会自动处理这种内嵌的JSON参数,得用正确的方式做编码。

为什么直接写JSON会报错?

URL里的{"level":"BIG"}包含双引号"、大括号{}这些URL保留字符,直接放在URL中会破坏URI的语法结构,new URI(...)解析时自然会抛出错误。而你之前尝试URLEncoder时出错,大概率是错误地编码了整个URL,导致URI变成非绝对路径,才出现IllegalArgumentException: URI is not absolute。

正确的解决方案有两种:

方案1:手动编码JSON参数,再通过占位符传递

先把Filter对象序列化成JSON字符串,单独编码这个字符串,再用RestTemplate的参数占位符传入,避免直接拼接URL:

// 1. 构建Filter对象并转成JSON字符串
Filter filter = new Filter();
filter.add("level", "BIG");
ObjectMapper objectMapper = new ObjectMapper();
String filterJson = objectMapper.writeValueAsString(filter);

// 2. 对JSON字符串进行URL编码(指定UTF-8字符集)
String encodedFilter = URLEncoder.encode(filterJson, StandardCharsets.UTF_8);

// 3. 用占位符传递编码后的参数,RestTemplate会自动拼接正确的URL
RestTemplate restTemplate = new RestTemplate();
Item item = restTemplate.getForObject(
    "http://127.0.0.1:8080/items?filter={filter}",
    Item.class,
    encodedFilter
);

方案2:用UriComponentsBuilder自动编码(更推荐)

Spring提供的UriComponentsBuilder会自动帮你处理参数的URL编码,比手动编码更安全,不容易出错:

// 1. 构建Filter对象并转成JSON字符串
Filter filter = new Filter();
filter.add("level", "BIG");
ObjectMapper objectMapper = new ObjectMapper();
String filterJson = objectMapper.writeValueAsString(filter);

// 2. 用UriComponentsBuilder构建带编码参数的URI
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("http://127.0.0.1:8080/items")
    .queryParam("filter", filterJson)
    .build(true); // 参数true表示自动对查询参数进行URL编码

// 3. 发送请求
RestTemplate restTemplate = new RestTemplate();
Item item = restTemplate.getForObject(uriComponents.toUri(), Item.class);

额外说明

你的Filter类用@JsonAnySetter来接收动态的criteria是正确的,远程服务那边能正常把URL中编码后的JSON字符串反序列化成Filter对象,进而执行MongoDB的参数化查询。

内容的提问来源于stack exchange,提问作者Valeriy K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:34:39