Мне нужно сгенерировать href
в URI. Все легко, за исключением случаев, когда речь идет о зарезервированных символах, которые нуждаются в процентном кодировании, например. ссылка на /some/path;element
должна отображаться как <a href="/some/path%3Belement">
(я знаю, что path;element
представляет собой единый объект).
Изначально я искал библиотеку Java, которая это делала, но в итоге я сама что-то писала (посмотрите ниже, что не удалось с Java, поскольку этот вопрос не является специфичным для Java).
Итак, RFC 3986 подсказывает, когда НЕ кодировать. Это должно произойти, когда я прочитаю его, когда персонаж попадает под класс unreserved (ALPHA / DIGIT / "-" / "." / "_" / "~")
. Все идет нормально. Но как насчет противоположного случая? RFC только упоминает, что проценты (%
) всегда нуждаются в кодировании. Но как насчет других?
Вопрос: правильно ли предположить, что все, что не является безоговорочным, может/должно быть закодировано в процентах? Например, открытие скобки (
не обязательно требует кодирования, но точка с запятой ;
. Если я не кодирую его, я в конечном итоге ищу /first
*, следуя <a href="/first;second">
. Но после <a href="/first(second">
я всегда искал /first(second
, как и ожидалось. Меня смущает то, что как (
, так и ;
находятся в том же классе sub-delims
, что и RFC. Как я полагаю, кодирование всего не-безоговорочного - это безопасная ставка, но как насчет SEOability, удобство для пользователя, когда дело доходит до локализованных URI?
Теперь, что не удалось с Java libs. Я пробовал делать это, как, например,
new java.net.URI("http", "site", "/pa;th", null).toASCIISTring()
но это дает http://site/pa;th
, что бесполезно. Аналогичные результаты наблюдаются при:
-
javax.ws.rs.core.UriBuilder
- Spring UriUtils - я пробовал как
encodePath(String, String)
, так иencodePathSegment(String, String)
[*] /first
является результатом вызова HttpServletRequest.getServletPath()
на стороне сервера при нажатии <a href="/first;second">
EDIT: Мне, вероятно, стоит упомянуть, что это поведение наблюдалось при Tomcat, и я проверил, что Tomcat 6 и 7 ведут себя одинаково.