Как заставить 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?
Должен ли я использовать другой подход?