如何强制 URIBuilder.path(...) 对“%AD"等参数进行编码?此方法并不总是正确地用百分比编码参数 [英] How to force URIBuilder.path(...) to encode parameters like "%AD"? This method doesn't always encode parameters with percentage, correctly

查看:11
本文介绍了如何强制 URIBuilder.path(...) 对“%AD"等参数进行编码?此方法并不总是正确地用百分比编码参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何强制URIBuilder.path(...)"%AD"等参数进行编码?

How to force URIBuilder.path(...) to encode parameters like "%AD"?

URIBuilder 的方法pathreplacePathsegment 并不总是正确地用百分比编码参数.

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.

每次我调用 queryParamreplaceQueryParamsegment 方法时,我都可以将%"替换为%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.RuntimeDelegateImpl,因此容器加载该文件而不是我的 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 RuntimeDelegateimplementation.

是否可以提供我自己的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆