我似乎找不到明确提到这一点,但如果您使用 java.net.URI,您似乎无法发送转义的加号(“%2b”)作为查询 arg 值,因为查询 arg被逃脱。
// bad: http://example.com/foo?a=%252b
new URI("http", null, "example.com", 80, "/foo", "a=%2b", null);
尝试了一个实际的“+”字符,但它按原样发送,因此服务器会将其解释为空格。
// bad: http://example.com/foo?a=+
new URI("http", null, "example.com", 80, "/foo", "a=+", null);
所以我猜你只需要自己对查询 arg 键和值进行百分比编码,并使用不会转义的单参数 URI 构造函数?也许让 URI 转义“路径”,因为规则很棘手(例如,“+”字符在路径中表示加号,而不是空格):
// good: http://example.com/foo?a=%2b
new URI(new URI("http", null, "example.com", 80, "/foo", null, null).toASCIIString() + "?a=%2b");
此外,文档声称您可以创建这样的 URI,它将与源 URI 相同:
URI u = ...;
URI identical = new URI(u.getScheme(),
u.getUserInfo(),
u.getPath(), u.getQuery(),
u.getFragment());
但当它包含 %2b 时,情况并非如此
URI u = new URI("http://example.com:80/foo?a=%2b");
URI identical = ...; // not identical! http://example.com:80/foo?a=+
令人沮丧,我想这就是为什么每个人都使用 apache commons 或 spring 类来代替?
PS:http ://docs.oracle.com/javase/6/docs/api/java/net/URI.html引用了“以下身份也持有”部分中不存在的 URI 构造函数。它需要删除“权限”参数。