我的Java独立应用程序从用户那里获得一个URL(指向一个文件),我需要点击它并下载它。我面临的问题是,我不能正确编码HTTP URL地址…

例子:

URL:  http://search.barnesandnoble.com/booksearch/first book.pdf

java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");

回报我。

http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf

但是,我想要的是

http://search.barnesandnoble.com/booksearch/first%20book.pdf

(空格替换为%20)

我猜URLEncoder不是为编码HTTP url设计的…JavaDoc说“HTML表单编码的实用程序类”…还有别的办法吗?


当前回答

我创建了一个新项目来帮助构建HTTP url。库将自动URL编码路径段和查询参数。

您可以在https://github.com/Widen/urlbuilder上查看源代码并下载二进制文件

这个问题中的URL示例:

new UrlBuilder("search.barnesandnoble.com", "booksearch/first book.pdf").toString()

生产

http://search.barnesandnoble.com/booksearch/first%20book.pdf

其他回答

我同意马特的观点。事实上,我从未在教程中看到过很好的解释,但一个问题是如何编码URL路径,另一个非常不同的问题是如何编码附加到URL的参数(“?”符号后面的查询部分)。它们使用类似的编码,但并不相同。

专门用于空白字符的编码。URL路径需要编码为%20,而查询部分允许使用%20和“+”符号。最好的方法是使用Web浏览器对我们的Web服务器进行测试。

对于这两种情况,我总是会编码组件组件,而不是整个字符串。实际上URLEncoder允许查询部分这样做。对于路径部分,您可以使用类URI,尽管在本例中它要求整个字符串,而不是单个组件。

无论如何,我相信避免这些问题的最好方法是使用个人无冲突的设计。怎么做?例如,我从来不使用a-Z, a-Z, 0-9和_以外的字符命名目录或参数。这样,唯一需要做的就是对每个参数的值进行编码,因为它可能来自用户输入,使用的字符是未知的。

除了Carlos Heuberger的回复: 如果需要不同于默认值(80)的参数,则应该使用7参数构造函数:

URI uri = new URI(
        "http",
        null, // this is for userInfo
        "www.google.com",
        8080, // port number as int
        "/ig/api",
        "weather=São Paulo",
        null);
String request = uri.toASCIIString();

如果你有一个URL,你可以将URL . tostring()传递给这个方法。首先解码,以避免双重编码(例如,编码空格会得到%20,编码百分号会得到%25,因此双重编码将把空格变成%2520)。然后,像上面解释的那样使用URI,添加URL的所有部分(这样就不会删除查询参数)。

public URL convertToURLEscapingIllegalCharacters(String string){
    try {
        String decodedURL = URLDecoder.decode(string, "UTF-8");
        URL url = new URL(decodedURL);
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); 
        return uri.toURL(); 
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}

我创建了一个新项目来帮助构建HTTP url。库将自动URL编码路径段和查询参数。

您可以在https://github.com/Widen/urlbuilder上查看源代码并下载二进制文件

这个问题中的URL示例:

new UrlBuilder("search.barnesandnoble.com", "booksearch/first book.pdf").toString()

生产

http://search.barnesandnoble.com/booksearch/first%20book.pdf

我开发了一个用于此目的的库:galimatias。它解析URL的方式与web浏览器相同。也就是说,如果一个URL在浏览器中工作,它将被galimatias正确解析。

在这种情况下:

// Parse
io.mola.galimatias.URL.parse(
    "http://search.barnesandnoble.com/booksearch/first book.pdf"
).toString()

会给你:http://search.barnesandnoble.com/booksearch/first%20book.pdf。当然,这是最简单的情况,但它可以用于任何东西,远远超出java.net.URI。

你可以在https://github.com/smola/galimatias上查看