Кодування URL-адрес в Android


336

Як кодувати URL-адресу в Android?

Я думав, що це так:

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

Якщо я вищевикладене, http://в urlAsStringзаміщається http%3A%2F%2Fв encodedURLа потім я отримую , java.net.MalformedURLExceptionколи я використовую URL.

Відповіді:


630

Ви не кодуєте всю URL-адресу, лише її частини, що надходять із "ненадійних джерел".

String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;

Крім того , ви можете використовувати Strings.urlEncode (Рядок Str) з DroidParts , проливають перевірені виключення.

Або використовувати щось подібне

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();

1
Що робити, якщо вся URL-адреса недостовірна? Чи слід кодувати все, крім протоколу? Я начебто очікував зручності для цього.
hpique

5
Тоді це просто зламана URL-адреса. Ідея полягає у тому, щоб запобігти порушенню URL-адреси запиту.
Янченко

5
@hgpc - подивіться у розділі 3 RFC3986 ( tools.ietf.org/html/rfc3986#section-3 ). Він розповідає про те, як кодувати різні частини URI. На жаль, кожна частина URI (хост, шлях, запит тощо) має дещо різні правила кодування.
Д.Шоулі

2
Це добре, якщо ви просто маєте справу з певною частиною URL-адреси, і ви знаєте, як створити або відновити URL-адресу. Більш загальний підхід, який може обробляти будь-яку URL-адресу, див. Мою відповідь нижче.
Крейг Б

8
Чому я отримую попередження про анулювання, використовуючи це? Використовується Uri.encode(query);замість цього.
prasanthv

166

Я збираюся додати тут одну пропозицію. Це можна зробити, щоб уникнути необхідності отримати будь-які зовнішні бібліотеки.

Спробуйте:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

Ви можете бачити, що в цій конкретній URL-адресі мені потрібно кодувати ці пробіли, щоб я міг використовувати його для запиту.

Це використовує кілька функцій, доступних для вас в класах Android. По-перше, клас URL може розбити URL-адресу на належні компоненти, тому немає необхідності виконувати роботу з пошуку / заміни рядків. По-друге, цей підхід використовує особливість класу URI, що належним чином виходить з компонентів, коли ви створюєте URI через компоненти, а не з одного рядка.

Краса такого підходу полягає в тому, що ви можете взяти будь-яку дійсну URL-адресу та працювати з цим, не потребуючи жодних спеціальних знань про це.


19
Це має бути правильна відповідь. це формальний і зрозумілий спосіб зробити це
Асанка Сенавіратна

3
Також може бути хорошою ідеєю urldecode urlStr, перш ніж надсилати його до конструктора URL. URLDecoder.decode (urlStr)
Якоб Ерікссон

1
Дякую за пост :) Але я зіткнувся з проблемою. Якщо URL вже частково закодований, він кодує вже кодовані частини. Що я повинен зробити? Наприклад: dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/…% 20 кодується до% 2520
berserk

2
@berserk Якщо він уже закодований, не кодуйте його. Ви не повинні входити в стан, де він частково закодований, або ви не впевнені, чи він закодований.
Маркіз Лорн

3
Цей метод не кодує символи типу ğ до% C4% 9F. Прийнято одне кодування!
Олександр Прокоф’єв

74

Для android я б використав String android.net.Uri.encode (String s)

Кодує символи в даному рядку як "%" - октети, що уникнули, використовуючи схему UTF-8. Букви ("AZ", "az"), цифри ("0-9"), а також незарезервовані символи ("_- !. ~ '() *") залишаються неушкодженими. Кодує всі інші символи.

Ex /

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);

2
На жаль Uri.encode("a=1&b=1")продукує, a%3D1%26b%3D1але очікуєтьсяa=1&b=1
loentar

14
@loentar Очікуваний результат. Якщо користувач вводить a=1&b=1як запит, ви хочете запитувати саме це.
Anubian Noob

Наскільки це відрізняється від URLEncoder.encode (StringHere, "UTF-8")
застряглий потік

@stuckedoverflow Для однієї речі, Uri.encode (str) не кидає перевірений виняток на відміну від URLEncoder.encode (str, "UTF-8")
deekshith

50

Також ви можете використовувати це

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

це найпростіший метод


1
це не найкраще рішення, але це, безумовно, приємне швидке виправлення ... подяка
Себастьян Брейт

4
Це найшвидший виправлення, коли вся URL-адреса недостовірна. Дякую!
user1032613

Ви впевнені, що% слід дозволити? Чи не слід його кодувати?
MediumOne

1
Як кодувати цей URL, щоб мати змогу поділитися, а потім користувач зможе відкрити посилання та подивитися сторінку: yazd20.com//News/2015/11/ استند-آب-كمدي-حسن-ريوندي-در-يزد. Html
Ахмад Ебрагімі

3
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

1

ви можете використовувати нижче наведені методи

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

або

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

другий краще, ніж перший.


0

Знайдіть арабські символи та замініть їх кодуванням UTF-8. щось на зразок цього:

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.