如何强制 URIBuilder.path(...) 对“%AD"等参数进行编码?此方法并不总是正确地用百分比编码参数 [英] How to force URIBuilder.path(...) to encode parameters like "%AD"? This method doesn't always encode parameters with percentage, correctly
问题描述
如何强制URIBuilder.path(...)
对"%AD"
等参数进行编码?
How to force URIBuilder.path(...)
to encode parameters like "%AD"
?
URIBuilder
的方法path
、replacePath
和segment
并不总是正确地用百分比编码参数.
The methods path
, replacePath
and segment
of URIBuilder
do not always encode parameters with percentage, correctly.
当参数包含字符%"后跟两个字符共同构成 URL 编码字符时,%"不编码为%25".
When a parameter contains the character "%" followed by two characters that together form an URL-encoded character, the "%" is not encoded as "%25".
例如
URI uri = UriBuilder.fromUri("https://dummy.com").queryParam("param", "%AD");
String test = uri.build().toString();
测试"是https://dummy.com?param=%AD"
但它应该是https://dummy.com?param=%25AD"(带有字符%"编码为%25")
"test" is "https://dummy.com?param=%AD"
But it should be "https://dummy.com?param=%25AD" (with the character "%" encoded as "%25")
UriBuilderImpl.queryParam(...)
方法在%"后面的两个字符是十六进制时的行为是这样的.即,方法com.sun.jersey.api.uri.UriComponent.isHexCharacter(char)"对于%"后面的字符返回 true.
The method UriBuilderImpl.queryParam(...)
behaves like this when the two characters following the "%" are hexadecimal. I.e, the method "com.sun.jersey.api.uri.UriComponent.isHexCharacter(char)" returns true for the characters following the "%".
我认为 UriBuilderImpl 的行为是正确的,因为我猜它试图不对已经编码的参数进行编码.但在我的场景中,我永远不会尝试使用已经编码的参数创建 URL.
I think the behavior of UriBuilderImpl is correct because I guess it tries to not encode parameters that already are encoded. But in my scenario, I will never try to create URLs with parameters that already encoded.
我该怎么办?
我的 Web 应用程序使用 Jersey,并且在许多地方我使用类 UriBuilder 构建 URI 或调用 UriInfo
对象的方法 getBaseUriBuilder
.
My Web application uses Jersey and in many places I build URIs using the class UriBuilder or invoke the method getBaseUriBuilder
of UriInfo
objects.
每次我调用 queryParam
、replaceQueryParam
或 segment
方法时,我都可以将%"替换为%25".但我正在寻找一个不那么繁琐的解决方案.
I can replace "%" with "%25", every time I invoke the methods queryParam
, replaceQueryParam
or segment
. But I am looking for a less cumbersome solution.
如何让 Jersey 返回我自己的 UriBuilder 实现?
我想创建一个扩展 UriBuilderImpl 的类,它覆盖这些方法并在调用 super.queryParam(...)
或其他任何东西之前执行此替换.
I thought of creating a class that extends UriBuilderImpl that overrides these methods and that perform this replacing before invoking super.queryParam(...)
or whatever.
在调用 UriBuilder.fromURL(...)
、UriInfo.getBaseUriBuilder(...) 等时,有什么方法可以让 Jersey 返回我自己的 UriBuilder 而不是 UriBuilderImpl?
Is there any way of making Jersey to return my own UriBuilder instead of UriBuilderImpl, when invoking UriBuilder.fromURL(...)
, UriInfo.getBaseUriBuilder(...), etc?
看了RuntimeDelegate
方法,想到了扩展RuntimeDelegateImpl
.我的实现将覆盖方法 createUriBuilder(...)
,它会返回我自己的 UriBuilder
,而不是 UriBuilderImpl
.然后,我将添加文件 META-INF/services/javax.ws.rs.ext.RuntimeDelegate
并在其中添加我的 RuntimeDelegateImpl
的完整类名.
Looking at the method RuntimeDelegate
, I thought of extending RuntimeDelegateImpl
. My implementation would override the method createUriBuilder(...)
, which would return my own UriBuilder
, instead of UriBuilderImpl
.
Then, I would add the file META-INF/services/javax.ws.rs.ext.RuntimeDelegate
and in it, a the full class name of my RuntimeDelegateImpl
.
问题在于 jersey-bundle.jar 已经包含一个指向 com.sun.jersey 的
,因此容器加载该文件而不是我的 META-INF/services/javax.ws.rs.ext.RuntimeDelegate
.server.impl.provider.RuntimeDelegateImpljavax.ws.rs.ext.RuntimeDelegate
.因此,它不会加载我的 RuntimeDelegate
实现.
The problem is that the jersey-bundle.jar already contains a META-INF/services/javax.ws.rs.ext.RuntimeDelegate
that points to com.sun.jersey.server.impl.provider.RuntimeDelegateImpl
, so the container loads that file instead of my javax.ws.rs.ext.RuntimeDelegate
. Therefore, it does not load my RuntimeDelegate
implementation.
是否可以提供我自己的 RuntimeDelegate
实现?
Is it possible to provide my own implementation of RuntimeDelegate
?
我应该采取不同的方法吗?
Should I take a different approach?
推荐答案
UriBuilder
这可以在 Jersey 的 UriComponent 的帮助下实现或 URLEncoder 直接来自 Java:
UriBuilder
This is possible with help of UriComponent from Jersey or URLEncoder directly from Java:
UriBuilder.fromUri("https://dummy.com")
.queryParam("param",
UriComponent.encode("%AD",
UriComponent.Type.QUERY_PARAM_SPACE_ENCODED))
.build();
结果:
https://dummy.com/?param=%25AD
或者:
UriBuilder.fromUri("https://dummy.com")
.queryParam("param", URLEncoder.encode("%AD", "UTF-8"))
.build()
将导致:
https://dummy.com/?param=%25AD
对于更复杂的示例(即在查询参数中编码 JSON),这种方法也是可能的.假设您有一个类似 {"Entity":{"foo":"foo","bar":"bar"}}
的 JSON.使用 UriComponent
编码时,查询参数的结果如下所示:
For a more complex examples (i.e. encoding JSON in query param) this approach is also possible. Let's assume you have a JSON like {"Entity":{"foo":"foo","bar":"bar"}}
. When encoded using UriComponent
the result for query param would look like:
https://dummy.com/?param=%7B%22Entity%22:%7B%22foo%22:%22foo%22,%22bar%22:%22bar%22%7D%7D
这样的 JSON 甚至可以通过 @QueryParam
注入到资源字段/方法参数中(参见 查询参数中的 JSON 或如何通过 JAX-RS 参数注释注入自定义 Java 类型).
JSON like this could be even injected via @QueryParam
into resource field / method param (see JSON in Query Params or How to Inject Custom Java Types via JAX-RS Parameter Annotations).
您使用哪个泽西岛版本?在您提到 Jersey 2 的标签中,但在 RuntimeDelegate
部分中您使用的是 Jersey 1 的东西.
Which Jersey version do you use? In the tags you mention Jersey 2 but in the RuntimeDelegate
section you're using Jersey 1 stuff.
这篇关于如何强制 URIBuilder.path(...) 对“%AD"等参数进行编码?此方法并不总是正确地用百分比编码参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!