Spring MVC中RestTemplate如何传递含双引号的过滤器参数?
解决RestTemplate传递含双引号、大括号的URL参数问题
问题原因
RestTemplate的URL解析机制会把{}识别为路径变量占位符,不管它出现在查询参数还是路径中。你两种方式失败的核心原因:
- 直接构造URL时,
{billid=%22P1yhABCnWJ7WhI%22}被RestTemplate误判为需要填充的变量,但没有提供对应值 - 变量替换方式中,
{filter}是合法占位符,但你传入的{billid=%22P1yhABCnWJ7WhI%22}里的{}又被解析成新的占位符,导致变量数量不匹配
三种可行解决方法
方法1:用UriComponentsBuilder构建URL(推荐)
UriComponentsBuilder会自动处理特殊字符编码和大括号解析,是最安全的实现方式:
// 直接写原始双引号,工具会自动编码为%22 String queryExpr = "test.link.packets{billid=\"P1yhABCnWJ7WhI\"}"; UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl("https://test.env123.com:8081/select/0/prometheus/api/v1/query_range") .queryParam("query", queryExpr) .queryParam("start", "2023-08-10T01:02:03Z") .queryParam("end", "2023-08-26T01:02:03Z"); URI uri = uriBuilder.build().encode().toUri(); ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);
方法2:转义URL中的大括号
如果一定要用变量替换语法,需把查询参数里的固定大括号用{{}}转义(RestTemplate会将{{}}解析为单个{}),变量部分用正常占位符:
String billIdValue = "\"P1yhABCnWJ7WhI\""; // 也可直接写%22P1yhABCnWJ7WhI%22 String requestURL = "https://test.env123.com:8081/select/0/prometheus/api/v1/query_range?query=test.link.packets{{billid={0}}}&start=2023-08-10T01:02:03Z&end=2023-08-26T01:02:03Z"; ResponseEntity<String> result = restTemplate.getForEntity(requestURL, String.class, billIdValue);
方法3:手动构造URI对象
如果已提前完成URL编码,直接用new URI()构造URI对象传递给RestTemplate(RestTemplate对URI对象不会再做编码或占位符解析):
String encodedQuery = "test.link.packets{billid=%22P1yhABCnWJ7WhI%22}"; String fullUrl = "https://test.env123.com:8081/select/0/prometheus/api/v1/query_range?query=" + encodedQuery + "&start=2023-08-10T01:02:03Z&end=2023-08-26T01:02:03Z"; URI uri = new URI(fullUrl); ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);
内容的提问来源于stack exchange,提问作者Nitish K
相关产品推荐
相关产品推荐

