Есть ли какие-либо опасения по поводу выполнения URLDecoder для URL, который не был закодирован?
В настоящее время включение URLEncoder и URLDecoder в некоторый код. Уже сохранено множество URL-адресов, которые будут обработаны подпрограммой URLDecoder, которая изначально не была обработана подпрограммой URLEncoder.
Судя по некоторым тестам, проблем не возникнет, но, разумеется, я не протестировал все сценарии.
Я заметил некоторые символы, такие как /
которые, как правило, кодируются, обрабатываются просто путем поиска процедурой декодирования, даже если они изначально не кодируются.
Это привело меня к упрощенному анализу. Похоже, процедура URLDecoder по существу проверяет URL для %
и следующие 2 байта (при условии использования UTF-8). Пока нет %
в ранее сохраненных URL-адресах не должно быть проблем при обработке подпрограммой URLDecoder. Звучит ли это правильно?
1 ответ
Да, хотя это будет работать для "простых" случаев, вы можете столкнуться с а) исключениями или б) неожиданным поведением при вызове URLDecoder.decode
для незашифрованного URL, который содержит определенные специальные символы.
Рассмотрим следующий пример: java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern
для третьего теста, и он изменит URL-адрес без исключения для второго теста (в то время как обычное кодирование / декодирование работает без проблем):
import java.net.URLDecoder;
import java.net.URLEncoder;
public class Test {
public static void main(String[] args) throws Exception {
test("http://www.foo.bar/");
test("http://www.foo.bar/?q=a+b");
test("http://www.foo.bar/?q=äöüß%"); // Will throw exception
}
private static void test(String url) throws Exception {
String encoded = URLEncoder.encode(url, "UTF-8");
String decoded = URLDecoder.decode(encoded, "UTF-8");
System.out.println("encoded: " + encoded);
System.out.println("decoded: " + decoded);
System.out.println(URLDecoder.decode(decoded, "UTF-8"));
}
}
Вывод (обратите внимание, как +
знак исчезает):
encoded: http%3A%2F%2Fwww.foo.bar%2F
decoded: http://www.foo.bar/
http://www.foo.bar/
encoded: http%3A%2F%2Fwww.foo.bar%2F%3Fq%3Da%2Bb
decoded: http://www.foo.bar/?q=a+b
http://www.foo.bar/?q=a b
encoded: http%3A%2F%2Fwww.foo.bar%2F%3Fq%3D%C3%A4%C3%B6%C3%BC%C3%9F%25
decoded: http://www.foo.bar/?q=äöüß%
Exception in thread "main" java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern
at java.net.URLDecoder.decode(Unknown Source)
at Test.test(Test.java:16)
См. Javadoc URLDecoder для двух случаев:
- Знак плюс "+" преобразуется в пробел " " .
- Последовательность в форме "%xy" будет рассматриваться как представляющая байт, где xy - это шестнадцатеричное представление из 8 битов, состоящее из двух цифр. Затем все подстроки, которые содержат одну или несколько из этих последовательностей байтов последовательно, будут заменены символом (символами), кодирование которого привело бы к этим последовательным байтам. Может быть указана схема кодирования, используемая для декодирования этих символов, или, если она не указана, будет использоваться кодировка платформы по умолчанию.
Если вы уверены, что ваши некодированные URL не содержат +
или же %
тогда я бы сказал, что это безопасно позвонить URLDecoder.decode
, В противном случае я бы посоветовал реализовать дополнительные проверки, например, попытаться декодировать и сравнить с оригиналом (см. Этот вопрос по SO).