【发布时间】:2011-09-11 08:51:47
【问题描述】:
我有一个相当典型的 REST API,除了资源的 id 不是整数,而是字符串,通常包含 / 字符。因此,如果客户的 id 是 string/with/slashes,那么该客户的 URI 应该是 http://localhost/customers/string%2Fwith%2Fslashes。返回客户列表时,我想用UriBuilder 构造该URI,这样我就可以将它放在ATOM 样式链接元素的href 中。但这并不完全奏效。这是一个小测试类,说明了我的意思:
@Path("/customers")
public class JerseyTest {
@Path("{id}")
public Customer getCustomer(@PathParam("{id}") String id) {
return null;
}
public static void main(String[] args) {
buildURI("string#with#hashes"); // => http://localhost/customers/string%23with%23hashes
buildURI("string/with/slashes"); // => http://localhost/customers/string/with/slashes
}
public static void buildURI(String id) {
UriBuilder builder = UriBuilder.fromUri("http://localhost");
builder.path(JerseyTest.class).path(JerseyTest.class, "getCustomer");
URI uri = builder.build(id);
System.out.println(uri);
}
}
# 会按照我的预期进行编码,但 / 不会。我尝试改用builder.build(URLEncoder.encode(id)),但是UriBuilder 对% 进行了编码,所以你得到.../string%252Fwith%252Fslashes!
在我看来,它编码 # 和 % 而不是 / 似乎不一致,但我怀疑有一个我没有看到的充分理由。所以我的问题是:
- 如何让 UriBuilder 给我
.../string%2Fwith%2Fslashes,这是导致 Jersey 调用getCustomer且id等于string/with/slashes的 URI? 编辑:我发现了一种解决方法:builder.buildFromEncoded(URLEncoder.encode(id))。让这个问题悬而未决,希望得到第二部分的答案...... - 更一般地说,为什么
UriBuilder.build对一些特殊字符进行编码,而对其他字符不进行编码?
我找到了How do I encode URI parameter values?,其中接受的答案是“使用 UriBuilder”。好吧,我正在使用它,但显然我使用不正确。
【问题讨论】:
-
在黑暗中拍摄,但是当您使用 unicode 转义值时会发生什么:
buildURI("string\u002fwith\u002fslashes")? -
对于信息,
URI.toString方法修改地址。URI.getPath不要。看一下com.sun.jersey.api.uri.UriComponent.encode(s, t),到%7...的转换就在那里完成了。/是 URI 的一部分,因此,也许有办法逃脱它们。 (我一直在挖掘) -
@stand 我很确定
"string\u002fwith\u002fslashes"编译为与"string/with/slashes"完全相同的字节码,但值得一试。所以我试了一下;相同的输出。不过感谢您的想法! -
@yves 我找到了第 1 部分的解决方案并将其编辑到问题中。如果您发现与第 2 部分相关的任何内容,请告诉我!
-
URLEncoder 的缺点是它用加号 ("foo bar" -> "foo+bar") 替换空格,而你会期望 %20 ("foo bar" -> "foo%20bar ")
标签: rest jersey urlencode jax-rs