如何用Java进行URL解码?


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编码的String ..?
Crackerplace,2011年

问题在于,仅因为URL可以是UTF-8,所以问题实际上与UTF-8 无关。我已经适当地编辑了问题。
克里斯·杰斯特·杨

从理论上讲可能是,但是示例中的字符串不是UTF-8编码的字符串。这是一个URL编码的ASCII字符串。因此,标题具有误导性。
斯蒂芬·C

还值得注意的是,url字符串中的所有字符都是ASCII,并且在对字符串进行URL解码之后也是如此。 '%'是ASCII字符,%xx如果xx小于(十六进制),则表示ASCII字符80
斯蒂芬·C

Answers:


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 Charset为该API 添加了直接支持,这意味着无需捕获UnsupportedEncodingException:

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

请注意,字符编码(例如UTF-8或ASCII)决定了字符到原始字节的映射。有关字符编码的良好介绍,请参见本文


1
上的方法URLDecoder是静态的,因此您不必创建它的新实例。
laz 2011年

2
@Trismegistos "UTF-8"根据Java 7 API文档,仅弃用了不指定字符编码(第二个参数)的版本。使用带有两个参数的版本。
Jesper

23
如果使用Java 1.7+,则可以使用“ UTF-8”字符串的静态版本:StandardCharsets.UTF_8.name()来自此软件包:java.nio.charset.StandardCharsets。与此相关:链接
Shahar 2014年

1
对于字符编码,这也使一篇很棒的文章balusc.blogspot.in/2009/05/unicode-how-to-get-characters-right.html
crackerplace 2014年

4
请注意这一点。如此处所述:blog.lunatech.com/2009/02/03/… 这与URL 无关,而是与HTML表单编码有关。
米哈尔(Michal)2015年


47

这已经被回答过了(尽管这个问题是第一个!):

“您应该使用java.net.URI来执行此操作,因为URLDecoder类会进行x-www-form-urlencoded解码,这是错误的(尽管名称如此,但它用于表单数据)。”

URL类文档所述:

建议的管理URL编码和解码的方法是使用URI,并使用toURI()URI.toURL()在这两个类之间进行转换。

URLEncoder的URLDecoder类也可以使用,但只为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.
Emerson Farrugia

1
URI的getPath()仅返回URI的路径部分,如上所述。
Pelpotronic

2
除非我弄错了,否则已知“路径”是URI中授权部分之后的那部分(有关路径的定义,请参见:en.wikipedia.org/wiki/Uniform_Resource_Identifier)-在我看来,我所看到的行为是是标准/正确的行为。我正在使用Java 1.8.0_101(在Android Studio上)。我很想知道调用“ getAuthority()”后会得到什么。即使是本文/示例,也似乎表明路径仅是其URI的/ public / manual / appliances部分:quepublishing.com/articles/article.aspx?p=26566&seqNum=3
Pelpotronic

1
@Pelpotronic帖子中的代码实际上确实打印了它显示的输出(至少对我而言)。我认为其原因在于,由于URL编码,URI构造函数实际上将整个字符串(https%3A%2F...)视为URI的路径。没有权限或查询等。可以通过在URI对象上调用相应的get方法来进行测试。如果将解码后的文本传递给URI构造函数:new URI("https://mywebsite/do....."),则调用getPath()和其他方法将给出正确的结果。
克鲁夫(Kröw)


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
您能否详细说明您的答案,并提供有关您提供的解决方案的更多说明?
abarisone 2015年


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 "";
    }
}

请注意,异常处理可能会更好,但是与该示例无关。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.