本文介绍了如何强制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.server.impl.provider.RuntimeDelegateImplMETA-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 RuntimeDelegateimplementation.

是否可以提供我自己的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"之类的参数进行编码?此方法并不总是正确地用百分比编码参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 16:05