spring - 调用 Spring RestController 时使用 Spring 的 RestTemplate 转义 URL 变量的正确方法是什么?
问题描述
当调用RestTemplate.exchange
做一个get请求时,比如:
String foo = "fo+o";
String bar = "ba r";
restTemplate.exchange("http://example.com/?foo={foo}&bar={bar}", HttpMethod.GET, null, foo, bar)
为获取请求正确转义 URL 变量的正确方法是什么?
具体来说,我如何+
正确地转义 pluses (),因为Spring 将其解释为空格,因此,我需要对它们进行编码。
我试过UriComponentsBuilder
这样使用:
String foo = "fo+o";
String bar = "ba r";
UriComponentsBuilder ucb = UriComponentsBuilder.fromUriString("http://example.com/?foo={foo}&bar={bar}");
System.out.println(ucb.build().expand(foo, bar).toUri());
System.out.println(ucb.build().expand(foo, bar).toString());
System.out.println(ucb.build().expand(foo, bar).toUriString());
System.out.println(ucb.build().expand(foo, bar).encode().toUri());
System.out.println(ucb.build().expand(foo, bar).encode().toString());
System.out.println(ucb.build().expand(foo, bar).encode().toUriString());
System.out.println(ucb.buildAndExpand(foo, bar).toUri());
System.out.println(ucb.buildAndExpand(foo, bar).toString());
System.out.println(ucb.buildAndExpand(foo, bar).toUriString());
System.out.println(ucb.buildAndExpand(foo, bar).encode().toUri());
System.out.println(ucb.buildAndExpand(foo, bar).encode().toString());
System.out.println(ucb.buildAndExpand(foo, bar).encode().toUriString());
并打印:
http://example.com/?foo=fo+o&bar=ba%20r
http://example.com/?foo=fo+o&bar=ba r
http://example.com/?foo=fo+o&bar=ba r
http://example.com/?foo=fo+o&bar=ba%20r
http://example.com/?foo=fo+o&bar=ba%20r
http://example.com/?foo=fo+o&bar=ba%20r
http://example.com/?foo=fo+o&bar=ba%20r
http://example.com/?foo=fo+o&bar=ba r
http://example.com/?foo=fo+o&bar=ba r
http://example.com/?foo=fo+o&bar=ba%20r
http://example.com/?foo=fo+o&bar=ba%20r
http://example.com/?foo=fo+o&bar=ba%20r
在某些情况下,空格被正确转义,但加号永远不会被转义。
我也试过UriTemplate
这样:
String foo = "fo+o";
String bar = "ba r";
UriTemplate uriTemplate = new UriTemplate("http://example.com/?foo={foo}&bar={bar}");
Map<String, String> vars = new HashMap<>();
vars.put("foo", foo);
vars.put("bar", bar);
URI uri = uriTemplate.expand(vars);
System.out.println(uri);
结果完全相同:
http://example.com/?foo=fo+o&bar=ba%20r
解决方案
显然,这样做的正确方法是定义工厂并更改编码模式:
String foo = "fo+o";
String bar = "ba r";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
URI uri = factory.uriString("http://example.com/?foo={foo}&bar={bar}").build(foo, bar);
System.out.println(uri);
打印出来:
http://example.com/?foo=fo%2Bo&bar=ba%20r
这记录在这里:https ://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#web-uri-encoding
推荐阅读
- javascript - 如何递归循环遍历对象数组并使用javascript找到匹配id的索引并做出反应?
- android - 如何在最新的android studio版本中安装android support repository v23.3.0?
- python - 字符串连接-TypeError:一元+的错误操作数类型:'str'
- python - 函数调用的高效或混乱使用
- c++ - 使用 boost 编译时出现序列化错误
- c - 如何使用 pthread 从两个数组中查找公共值
- recursion - 打印出树中的所有节点时,递归还是迭代更有效?
- javascript - Javascript(浮点问题):有没有可靠的方法将分数转换为小数然后再返回?
- sql - Oracle SQL 在字符串的数字部分之后选择字符
- python - 使用 networkx (Python) 创建和执行任务工作流