Сохранение экранированных символов при создании URI в Java - PullRequest
3 голосов
/ 20 октября 2011

Документация для java.net.URI указывает, что

Для любого URI, который ... и который не кодирует символы, кроме тех, которые должны быть заключены в кавычки, следующие символытакже удерживайте ...

Но как насчет URI, которые делают кодируют символы, которые не нужно заключать в кавычки?

URI test1 = new URI("http://foo.bar.baz/%E2%82%AC123");
URI test2 = new URI(test1.getScheme(), test1.getUserInfo(), test1.getHost(), test1.getPort(), test1.getPath(), test1.getQuery(), test1.getFragment());
assert test1.equals(test2); // blows up

Это не удается, потому чтоtest2 означает, что http://foo.bar.baz/€123 - с экранированными символами без экранирования.

Мой вопрос, таким образом: как я могу создать URI, равный test1 - сохраняясбежавшие персонажи - из его компонентов?Бесполезно использовать getRawPath() вместо getPath(), потому что тогда самим сбежавшим персонажам удаляются, и вы получаете http://foo.bar.baz/%25E2%2582%25AC123.

Дополнительные примечания:

  1. Донне спрашивайте, почему мне нужно сохранять экранированные символы, которые в теории не нужно экранировать - поверьте мне, вы не хотите знать.
  2. На самом деле я не хочу сохранять всеисходный URL, только большая его часть - возможно, заменив хост, порт, протокол и даже части пути, поэтому new URI(test1.toString()) не является ответом.Возможно, ответ состоит в том, чтобы делать все со строками и копировать способность класса URI анализировать и создавать URI в моем собственном коде, но это кажется глупым.

Обновлено для добавления:

Обратите внимание, что та же проблема существует с параметрами запроса и т. Д., Это не просто путь.

1 Ответ

1 голос
/ 25 октября 2011

Я думаю, этот хак подойдет вам:

    URI test1 = new URI("http://foo.bar.baz/example%E2%82%AC123");
URI test2 = new URI(test1.getScheme(),
                    test1.getUserInfo(),
                    test1.getHost(),
                    test1.getPort(),
                    test1.getPath(),
                    test1.getQuery(),
                    test1.getFragment());

test2 = new URI(test2.toASCIIString());

assert test1.equals(test2);

System.out.println(test1);
System.out.println(test2);

}

Я использую дополнительный шаг, используя toASCIIString ()

...