Як зробити розшифровку URL-адрес на Java?


323

У Java я хочу перетворити це:

https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest_type

До цього:

https://mywebsite/docs/english/site/mybook.do&request_type

Ось що я маю досі:

class StringUTF 
{
    public static void main(String[] args) 
    {
        try{
            String url = 
               "https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do" +
               "%3Frequest_type%3D%26type%3Dprivate";

            System.out.println(url+"Hello World!------->" +
                new String(url.getBytes("UTF-8"),"ASCII"));
        }
        catch(Exception E){
        }
    }
}

Але це не працює правильно. Що це %3Aі %2Fформати називається і як конвертувати їх?


@Stephen .. Чому URL-адреса не може бути кодованою рядком UTF-8 ..?
крекер

Проблема полягає в тому, що лише тому, що URL може бути UTF-8, питання насправді не має нічого спільного з UTF-8. Я відповідним чином редагував питання.
Кріс Єстер-Янг

Це може бути (теоретично), але рядок у вашому прикладі не є рядком, кодованим UTF-8. Це рядок, кодований URL-адресою ASCII. Отже, назва вводить в оману.
Стівен C

Варто також зазначити, що всі символи в urlрядку мають ASCII, і це також справедливо після розшифровки рядка URL. '%'є символом ASCII і %xxявляє собою знак ASCII, якщо xxвін менший (шістнадцятковий) 80.
Стівен C

Відповіді:


634

Це не має нічого спільного з кодуваннями символів, такими як UTF-8 або ASCII. Рядок, який у вас є, закодований URL . Цей вид кодування - щось зовсім інше, ніж кодування символів.

Спробуйте щось подібне:

try {
    String result = java.net.URLDecoder.decode(url, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
    // not going to happen - value came from JDK's own StandardCharsets
}

Java 10 додала пряму підтримку CharsetAPI, тобто немає необхідності ловити UnsupportedEncodingException:

String result = java.net.URLDecoder.decode(url, StandardCharsets.UTF_8);

Зауважте, що кодування символів (наприклад, UTF-8 або ASCII) є тим, що визначає відображення символів до необмежених байтів. Для кращого вступу до кодування символів дивіться цю статтю .


1
Методи увімкнено URLDecoderстатичні, тому вам не потрібно створювати новий примірник.
лаз

2
@Trismegistos Лише версія, де ви не вказуєте кодування символів (другий параметр, "UTF-8"), застаріла відповідно до документації API Java 7. Використовуйте версію з двома параметрами.
Джеспер

23
При використанні Java 1.7+ ви можете використовувати версію статичної рядка «UTF-8»: StandardCharsets.UTF_8.name()з цього пакета: java.nio.charset.StandardCharsets. Доречно для цього: посилання
Шахар

1
Для кодування символів це чудова стаття занадто balusc.blogspot.in/2009/05/unicode-how-to-get-characters-right.html
crackerplace

4
Будьте обережні з цим. Як зазначалося тут: blog.lunatech.com/2009/02/03/… Йдеться не про URL-адреси, а про кодування HTML-форм.
Міхал


47

На це відповіли раніше (хоча це питання було першим!):

"Для цього слід використовувати java.net.URI, оскільки клас URLDecoder робить декодування x-www-form-urlencoded, яке невірно (незважаючи на назву, це для даних форми)."

Як зазначено в документації про клас URL :

Рекомендованим способом управління кодуванням та декодуванням URL-адрес є використання URI та перетворення між цими двома класами за допомогою toURI () та URI.toURL () .

The URLEncoder і розкодування URL- адреси класи також можуть бути використані, але тільки про людське око кодування HTML, який не є таким же , як схема кодування , визначеної в RFC2396 .

В основному:

String url = "https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest_type";
System.out.println(new java.net.URI(url).getPath());

дасть вам:

https://mywebsite/docs/english/site/mybook.do?request_type

6
У Java 1.7 URLDecoder.decode(String, String)перевантаження не застаріло. Ви повинні мати на увазі URLDecoder.decode(String)перевантаження без кодування. Ви можете оновити свою публікацію для уточнення.
Аарон

2
Ця відповідь вводить в оману; ця блокова цитата не має нічого спільного з депресією. Javadoc застарілого методу заявляє, і я фактично цитую@deprecated The resulting string may vary depending on the platform's default encoding. Instead, use the decode(String,String) method to specify the encoding.
Емерсон Фарругія

1
getPath () для URI повертає лише частину шляху URI, як зазначено вище.
Пелпотронік

2
Якщо я не помиляюся, "шлях", як відомо, є тією частиною URI після авторитетної частини (див. En.wikipedia.org/wiki/Uniform_Resource_Identifier для визначення шляху) - мені здається поведінка, яку я бачу - це стандартна / правильна поведінка. Я використовую java 1.8.0_101 (в Android Studio). Мені буде цікаво побачити, що ви отримуєте під назвою "getAuthority ()". Навіть ця стаття / приклад, схоже, вказує на те, що шлях є лише / public / manual / devices
Pelpotronic

1
@Pelpotronic Код у пості насправді друкує висновок, який він показує (принаймні для мене). Я думаю, що причина цього полягає в тому, що через кодування URL-адреси конструктор URI насправді розглядає всю рядок ( https%3A%2F...) як просто шлях URI; немає повноважень, запитів тощо. Це можна перевірити, викликавши відповідні методи отримання об’єкта URI. Якщо ви передаєте декодований текст конструктору URI:, new URI("https://mywebsite/do.....")виклик getPath()та інші методи дадуть правильні результати.
Kröw

14

%3Aі %2Fє символами, кодованими URL-адресами. Використовуйте цей код Java для перетворення їх назад у :та/

String decoded = java.net.URLDecoder.decode(url, "UTF-8");

2
він також не конвертує% 2C, це (,)
vuhung3990

це потрібно загорнути в блок "пробувати / ловити". читайте докладніше про перевірені винятки (цей) проти неперевіреного stackoverflow.com/questions/6115896/…
Бруно Вулф,

5
 try {
        String result = URLDecoder.decode(urlString, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

5
public String decodeString(String URL)
    {

    String urlString="";
    try {
        urlString = URLDecoder.decode(URL,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block

        }

        return urlString;

    }

4
Чи можете ви детальніше розглянути свою відповідь, додавши трохи більше опису про рішення, яке ви надаєте?
абарізон


2
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;

public class URLDecoding { 

    String decoded = "";

    public String decodeMethod(String url) throws UnsupportedEncodingException
    {
        decoded = java.net.URLDecoder.decode(url, "UTF-8"); 
        return  decoded;
//"You should use java.net.URI to do this, as the URLDecoder class does x-www-form-urlencoded decoding which is wrong (despite the name, it's for form data)."
    }

    public String getPathMethod(String url) throws URISyntaxException 
    {
        decoded = new java.net.URI(url).getPath();  
        return  decoded; 
    }

    public static void main(String[] args) throws UnsupportedEncodingException, URISyntaxException 
    {
        System.out.println(" Here is your Decoded url with decode method : "+ new URLDecoding().decodeMethod("https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest_type")); 
        System.out.println("Here is your Decoded url with getPath method : "+ new URLDecoding().getPathMethod("https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest")); 

    } 

}

Ви можете вибрати свій метод розумно :)


0

Використання класу java.net.URI:

public String getDecodedURL(String encodedUrl) {
    try {
        URI uri = new URI(encodedUrl);
        return uri.getScheme() + ":" + uri.getSchemeSpecificPart();
    } catch (Exception e) {
        return "";
    }
}

Зверніть увагу, що обробка винятків може бути кращою, але це не дуже актуально для цього прикладу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.