问题描述
如何强制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.server.impl.provider.RuntimeDelegateImpl
的META-INF/services/javax.ws.rs.ext.RuntimeDelegate
,因此容器将加载该文件而不是我的javax.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
在泽西岛的 UriComponent 的帮助下,这是可能的或直接从Java中直接 URLEncoder :
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 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).
您使用哪个球衣版本?在标签中提到泽西岛2,但在RuntimeDelegate
部分中,您使用泽西岛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"之类的参数进行编码?此方法并不总是正确地用百分比编码参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!