Как заставить URIBuilder.path(...)
кодировать такие параметры, как "%AD"
?
Методы path
, replacePath
и segment
of URIBuilder
не всегда правильно кодируют параметры с процентом.
Когда параметр содержит символ "%" , за которым следуют два символа, которые вместе образуют символ с кодировкой URL, "%" не кодируется как "% 25".
Например
URI uri = UriBuilder.fromUri("https://dummy.com").queryParam("param", "%AD");
String test = uri.build().toString();
"test" - " https://dummy.com?param=%AD"
Но это должно быть " https://dummy.com?param=%25AD" (с символом "%", кодированным как "% 25" )
Метод UriBuilderImpl.queryParam(...)
ведет себя так, когда два символа, следующие за "%" , являются шестнадцатеричными. I.e, метод "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
.
Возможно ли предоставить мою собственную реализацию RuntimeDelegate
?
Должен ли я использовать другой подход?