Как заставить URIBuilder.path(...)
кодировать такие параметры, как "%AD"
?
Методы path
, replacePath
и segment
из URIBuilder
не всегда корректно кодируют параметры в процентах.
Если параметр содержит символ "%", за которым следуют два символа, которые вместе образуют символ в кодировке URL, "%" не кодируется как "%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")
Метод UriBuilderImpl.queryParam(...)
ведет себя так, когда два символа, следующие за "%", являются шестнадцатеричными. То есть метод «com.sun.jersey.api.uri.UriComponent.isHexCharacter(char)» возвращает true для символов, следующих за «%».
Я думаю, что поведение UriBuilderImpl правильное, потому что я предполагаю, что он пытается не кодировать параметры, которые уже закодированы. Но в моем сценарии я никогда не буду пытаться создавать URL-адреса с уже закодированными параметрами.
Что мне делать?
В моем веб-приложении используется Джерси, и во многих местах я создаю URI с помощью класса UriBuilder или вызываю метод getBaseUriBuilder
из UriInfo
объектов.
Я могу заменить "%" на "%25" каждый раз, когда я вызываю методы queryParam
, replaceQueryParam
или segment
. Но я ищу менее громоздкое решение.
Как заставить Джерси возвращать мою собственную реализацию UriBuilder?
Я подумал о создании класса, который расширяет UriBuilderImpl, который переопределяет эти методы и выполняет эту замену перед вызовом super.queryParam(...)
или чего-то еще.
Есть ли способ заставить Джерси возвращать мой собственный UriBuilder вместо UriBuilderImpl при вызове UriBuilder.fromURL(...)
, UriInfo.getBaseUriBuilder(...) и т. д.?
Глядя на метод RuntimeDelegate
, я подумал о расширении RuntimeDelegateImpl
. Моя реализация переопределит метод createUriBuilder(...)
, который вернет мой собственный UriBuilder
вместо UriBuilderImpl
. Затем я бы добавил файл META-INF/services/javax.ws.rs.ext.RuntimeDelegate
и в нем полное имя класса моего RuntimeDelegateImpl
.
Проблема в том, что jersey-bundle.jar уже содержит META-INF/services/javax.ws.rs.ext.RuntimeDelegate
, указывающий на com.sun.jersey.server.impl.provider.RuntimeDelegateImpl
, поэтому контейнер загружает этот файл вместо моего javax.ws.rs.ext.RuntimeDelegate
. Поэтому он не загружает мой RuntimeDelegate
implementation.
Можно ли предоставить собственную реализацию RuntimeDelegate
?
Должен ли я использовать другой подход?