Каков наилучший способ кодирования URL-адресов только ключей и параметров запроса в Java?

Я хотел бы кодировать только ключи запроса и параметры URL-адреса (не хочу кодировать /,? или &). Как лучше всего это сделать на Java?

Например, я хочу преобразовать

http://www.hello.com/bar/foo?a=,b &c =d

to

http://www.hello.com/bar/foo?a=%2Cb%20&c%20=d


person Popcorn    schedule 19.03.2014    source источник
comment
Извлечение и разбор компонентов запроса; восстановить URL-адрес. На практике я бы использовал замену регулярного выражения с соответствующей кодировкой, примененной к замене. Шаблон предоставленного URL-адреса с захватами может выглядеть так: \b(\w[^=]*)=([^&]*)   -  person user2864740    schedule 20.03.2014
comment
URL url = new URL(...); String query = URLEncoder.encode(url.getQuery(), ...); String encoded = url.getPath() + "?" + query; или что-то в этом роде; Я не помню особенностей различных URL.getXXX(), которые приходят мне в голову.   -  person Jason C    schedule 20.03.2014
comment
@ user2864740 Вы можете просто использовать URL для анализа и извлечения компонентов; а URLEncoder также является частью JDK и кодирует произвольные строки.   -  person Jason C    schedule 20.03.2014
comment
@JasonC Возможно, но я недостаточно уверен в том, как будет анализироваться первый URL-адрес, поскольку он требует некоторой снисходительности - особенно в данном случае в отношении имени параметра c; также может потребоваться дополнительный упрощенный синтаксический анализ, если также были включены различные неэкранированные/зарезервированные символы.   -  person user2864740    schedule 20.03.2014


Ответы (2)


Создайте URL-адрес примерно так:

String url = "http://www.hello.com/bar/foo?";
url += "a=" + URLEncoder.encode(value_of_a);
url += "&c=" + URLEncoder.encode(value_of_c);
person developerwjk    schedule 19.03.2014

Я собираюсь оставить фактическую кодировку компонента как предоставленную пользователем функцию. потому что это существующая хорошо обсуждаемая проблема без тривиального решения JCL .. В любом случае, ниже показано, как я бы решил эту конкретную проблему без использования сторонних библиотек.

Хотя регулярные выражения иногда приводят к двум проблемам, Я не решаюсь предложить более строгий подход, такой как URI потому что я не знаю, как это будет (или даже будет ли) работать с такими причудливыми недействительными URL-адресами. Таким образом, вот решение, использующее регулярное выражение с значение динамической замены.

// The following pattern is pretty liberal on what it matches;
// It ought to work as long as there is no unencoded ?, =, or & in the URL
// but, being liberal, it will also match absolute garbage input.
Pattern p = Pattern.compile("\\b(\\w[^=?]*)=([^&]*)");
Matcher m = p.matcher("http://www.hello.com/bar/foo?a=,b &c =d");
StringBuffer sb = new StringBuffer();
while (m.find()) {
    String key = m.group(1);
    String value = m.group(2);
    m.appendReplacement(sb,
        encodeURIComponent(key) + "=" encodeURIComponent(value));
}
m.appendTail(sb);

См. пример ideone с заполнителем encodeURIComponent.

person user2864740    schedule 19.03.2014