Comment faire le décodage d'URL en Java?

323

En Java, je veux convertir ceci:

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

Pour ça:

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

Voici ce que j'ai jusqu'à présent:

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){
        }
    }
}

Mais cela ne fonctionne pas correctement. Quelles sont ces %3Aet %2Fformats appelé et comment puis-je les convertir?

crackerplace
la source
@Stephen .. Pourquoi une URL ne peut-elle pas être une chaîne encodée en UTF-8 ..?
crackerplace
Le problème est que, simplement parce que l'URL peut être UTF-8, la question n'a vraiment rien à voir avec UTF-8. J'ai correctement édité la question.
Chris Jester-Young
Cela pourrait être (en théorie), mais la chaîne dans votre exemple n'est pas une chaîne codée UTF-8. Il s'agit d'une chaîne ASCII codée URL. Par conséquent, le titre est trompeur.
Stephen C
Il convient également de noter que tous les caractères de la urlchaîne sont ASCII, et cela est également vrai une fois la chaîne décodée par URL. '%'est un caractère ASCII et %xxreprésente un caractère ASCII si xxest inférieur à (hexadécimal) 80.
Stephen C

Réponses:

634

Cela n'a rien à voir avec les encodages de caractères tels que UTF-8 ou ASCII. La chaîne que vous y avez est encodée en URL . Ce type d'encodage est quelque chose de complètement différent de l'encodage de caractères.

Essayez quelque chose comme ceci:

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 a ajouté une prise en charge directe Charsetde l'API, ce qui signifie qu'il n'est pas nécessaire d'attraper UnsupportedEncodingException:

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

Notez qu'un codage de caractères (tel que UTF-8 ou ASCII) est ce qui détermine le mappage des caractères en octets bruts. Pour une bonne introduction aux encodages de caractères, consultez cet article .

Jesper
la source
1
Les méthodes sur URLDecodersont statiques, vous n'avez donc pas à en créer une nouvelle instance.
laz
2
@Trismegistos Seule la version où vous ne spécifiez pas l'encodage des caractères (le deuxième paramètre, "UTF-8") est déconseillée selon la documentation de l'API Java 7. Utilisez la version avec deux paramètres.
Jesper
23
Si vous utilisez Java 1.7+ , vous pouvez utiliser la version statique de la chaîne « UTF-8 »: à StandardCharsets.UTF_8.name()partir de ce paquet: java.nio.charset.StandardCharsets. Pertinent: lien
Shahar
1
Pour l'encodage de caractères, cela fait un excellent article trop balusc.blogspot.in/2009/05/unicode-how-to-get-characters-right.html
crackerplace
4
Soyez prudent avec cela. Comme indiqué ici: blog.lunatech.com/2009/02/03/… Il ne s'agit pas d'URL, mais du codage de formulaire HTML.
Michal
52

La chaîne que vous avez est application/x-www-form-urlencodedencodée.

Utilisez URLDecoder pour le convertir en chaîne Java.

URLDecoder.decode( url, "UTF-8" );
Alexander Pogrebnyak
la source
47

Cela a été répondu avant (bien que cette question était d' abord!):

"Vous devez utiliser java.net.URI pour ce faire, car la classe URLDecoder effectue le décodage x-www-form-urlencoded qui est incorrect (malgré le nom, c'est pour les données du formulaire)."

Comme l' indique la documentation des classes d' URL :

La méthode recommandée pour gérer le codage et le décodage des URL consiste à utiliser l' URI et à effectuer une conversion entre ces deux classes à l'aide de toURI () et URI.toURL () .

Les classes URLEncoder et URLDecoder peuvent également être utilisées, mais uniquement pour le codage de formulaire HTML, qui n'est pas le même que le schéma de codage défini dans RFC2396 .

Fondamentalement:

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

te donnera:

https://mywebsite/docs/english/site/mybook.do?request_type
Nick Grealy
la source
6
Dans Java 1.7, la URLDecoder.decode(String, String)surcharge n'est pas déconseillée. Vous devez faire référence à la URLDecoder.decode(String)surcharge sans l'encodage. Vous voudrez peut-être mettre à jour votre message pour clarification.
Aaron
2
Cette réponse est trompeuse; cette citation de bloc n'a rien à voir avec la dépréciation. Le Javadoc de la méthode obsolète déclare, et je cite en fait@deprecated The resulting string may vary depending on the platform's default encoding. Instead, use the decode(String,String) method to specify the encoding.
Emerson Farrugia
1
getPath () pour les URI ne renvoie que la partie chemin de l'URI, comme indiqué ci-dessus.
Pelpotronic
2
Sauf erreur, le "chemin" est connu pour être la partie d'un URI après la partie autorité (voir: en.wikipedia.org/wiki/Uniform_Resource_Identifier pour la définition du chemin) - il me semble le comportement que je vois est le comportement standard / correct. J'utilise java 1.8.0_101 (sur Android Studio). Je serais curieux de voir ce que vous obtenez lorsque "getAuthority ()" est appelé. Même cet article / exemple semble indiquer que le chemin n'est que la partie / public / manual / appliances de leur URI: quepublishing.com/articles/article.aspx?p=26566&seqNum=3
Pelpotronic
1
@Pelpotronic Le code dans le message imprime en fait la sortie qu'il affiche (au moins pour moi). Je pense que la raison en est que, en raison de l'encodage d'URL, le constructeur d'URI traite en fait la chaîne entière, ( https%3A%2F...), comme juste le chemin d'un URI; il n'y a pas d'autorité, ni de requête, etc. Cela peut être testé en appelant les méthodes get respectives sur l'objet URI. Si vous passez le texte décodé au constructeur URI:, l' new URI("https://mywebsite/do.....")appel getPath()et d'autres méthodes donneront des résultats corrects.
Kröw
14

%3Aet %2Fsont des caractères codés URL. Utilisez ce code java pour les reconvertir :et/

String decoded = java.net.URLDecoder.decode(url, "UTF-8");
laz
la source
2
il ne convertit pas aussi% 2C, c'est (,)
vuhung3990
cela doit être enveloppé dans un bloc try / catch .. En savoir plus sur les exceptions cochée (cette) contre un décochée stackoverflow.com/questions/6115896/...
Bruno Wolff
5
 try {
        String result = URLDecoder.decode(urlString, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
Hsm
la source
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;

    }
Ronak Poriya
la source
4
Pourriez-vous élaborer davantage votre réponse en ajoutant un peu plus de description sur la solution que vous proposez?
abarisone
3

J'utilise apache commons

String decodedUrl = new URLCodec().decode(url);

Le jeu de caractères par défaut est UTF-8

Trieur
la source
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")); 

    } 

}

Vous pouvez sélectionner votre méthode judicieusement :)

rinuthomaz
la source
0

Utilisation de la classe java.net.URI:

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

Veuillez noter que la gestion des exceptions peut être meilleure, mais ce n'est pas très pertinent pour cet exemple.

x7BiT
la source