Используя Java, я хочу удалить идентификатор фрагмента и выполнить простую нормализацию (например, строчные схемы, хосты) разнообразного набора URI. Входные и выходные URI должны быть эквивалентными в общем смысле HTTP.
Как правило, это должно быть просто. Однако для таких URI, как http://blah.org/A_%28Secret%29.xml#blah
, процент которых кодирует (Секрет)
, поведение java. util.URI
усложняет жизнь.
Метод нормализации должен вернуть http://blah.org/A_%28Secret%29.xml
, поскольку URI http://blah.org/A_%28Secret%29.xml
и http://blah.org/A_ (Secret) .xml
не эквивалентны в интерпретации [§2.2; RFC3968 ]
Итак, у нас есть два следующих метода нормализации:
URI u = new URI("http://blah.org/A_%28Secret%29.xml#blah");
System.out.println(u);
// prints "http://blah.org/A_%28Secret%29.xml#blah"
String path1 = u.getPath(); //gives "A_(Secret).xml"
String path2 = u.getRawPath(); //gives "A_%28Secret%29.xml"
//NORMALISE METHOD 1
URI norm1 = new URI(u.getScheme().toLowerCase(), u.getUserInfo(),
u.getHost().toLowerCase(), u.getPort(), path1,
u.getQuery(), null);
System.out.println(norm1);
// prints "http://blah.org/A_(Secret).xml"
//NORMALISE METHOD 2
URI norm2 = new URI(u.getScheme().toLowerCase(), u.getUserInfo(),
u.getHost().toLowerCase(), u.getPort(), path2,
u.getQuery(), null);
System.out.println(norm2);
// prints "http://blah.org/A_%2528Secret%2529.xml"
Как мы видим, URI анализируется и перестраивается без идентификатора фрагмента.
Однако для метода 1 u.getPath ()
возвращает незакодированный URI, который изменяет окончательный URI.
Для метода 2 u.getRawPath ()
возвращает исходный путь, но при передаче в конструктор URI
Java решает добавить двойное кодирование.
Это похоже на китайскую ловушку для пальцев.
Итак, два основных вопроса:
java.util.URI
чувствует необходимость играть с кодировкой? (Я бы предпочел не реализовывать нетривиальные методы синтаксического анализа / конкатенации java.util.URI
.)
РЕДАКТИРОВАТЬ: Вот дополнительная информация из URI
javadoc .
Конструктор с одним аргументом требует, чтобы любые недопустимые символы в его аргументе были заключены в кавычки, а сохраняет все экранированные октеты и другие присутствующие символы.
конструкторы с несколькими аргументами цитируют недопустимые символы в соответствии с требованиями компонентов, в которых они появляются. Эти конструкторы всегда цитируют символ процента ('%'). Все остальные символы сохраняются.
Методы getRawUserInfo, getRawPath , getRawQuery, getRawFragment, getRawAuthority и getRawSchemeSpecificPart возвращают значения своих соответствующих компонентов в необработанном виде, без интерпретации каких-либо экранированных октетов . Строки, возвращаемые этими методами, могут содержать как экранированные октеты, так и другие символы, и не будут содержать никаких недопустимых символов.
Методы getUserInfo, getPath , getQuery, getFragment, getAuthority и getSchemeSpecificPart декодируют любые экранированные октеты в их соответствующих компонентах. Строки, возвращаемые этими методами, могут содержать как другие символы, так и недопустимые символы, и не будут содержать никаких экранированных октетов.
Метод toString возвращает строку URI со всеми необходимыми кавычками, но может содержать другие символы.
Метод toASCIIString возвращает полностью закодированную строку URI в кавычках, не содержащую других символов.
Таким образом, я не могу использовать конструктор с несколькими аргументами, если кодировка URL-адреса не изменится внутри класса URI
. Тьфу!