Spring MVC无法解码RestTemplate传递的URL编码查询参数问题求助
问题原因
核心是RestTemplate对字符串类型的URI参数默认会执行二次URL编码:
你传入的字符串URI中scrollId已经预编码为FGluxxdw%3D%3D,RestTemplate处理字符串URI时会将其中的%符号再次编码为%25,最终发出的请求参数实际为FGluxxdw%253D%253D。服务端仅做一次解码后得到的是FGluxxdw%3D%3D,和预期的原始值FGluxxdw==不符,导致参数解析失败。
解决方案
可根据你的使用场景选择以下任意一种方案:
- 方案1:使用UriComponentsBuilder构造URI,交给RestTemplate完成编码(推荐)
不要自己预编码参数,直接传入原始参数值,由框架统一处理编码逻辑:
// 直接传入原始未编码的scrollId值 FGluxxdw== URI uri = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/order/scroll") .queryParam("size", 1) .queryParam("orderItemNumber", "XX1468") .queryParam("scrollId", "FGluxxdw==") .build() .toUri(); // 传入URI对象调用接口 this.restTemplate.exchange(uri, HttpMethod.GET, httpEntity, PRODUCT.class);
- 方案2:预编码的URI直接转换为URI对象传入
如果你已经提前完成了URI编码,不需要RestTemplate再次处理,直接将字符串转换为URI对象传入即可:
// 预编码完成的URI字符串 String encodedUri = "http://localhost:8080/order/scroll?size=1&orderItemNumber=XX1468&scrollId=FGluxxdw%3D%3D"; URI uri = URI.create(encodedUri); this.restTemplate.exchange(uri, HttpMethod.GET, httpEntity, PRODUCT.class);
- 方案3:UriComponentsBuilder标识为已编码
使用UriComponentsBuilder构造预编码的URI时,调用build方法传入true标识内容已编码,跳过编码流程:
URI uri = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/order/scroll") .queryParam("size", 1) .queryParam("orderItemNumber", "XX1468") .queryParam("scrollId", "FGluxxdw%3D%3D") .build(true) // true表示参数已编码,不再执行二次编码 .toUri(); this.restTemplate.exchange(uri, HttpMethod.GET, httpEntity, PRODUCT.class);
内容的提问来源于stack exchange,提问作者user11720476
相关产品推荐
相关产品推荐

