我的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表单编码的实用程序类”…还有别的办法吗?


当前回答

我用这个

org.apache.commons.text.StringEscapeUtils.escapeHtml4("my text % & < >");

添加这个依赖项

 <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.8</version>
    </dependency>

其他回答

我开发了一个比其他解决方案更稳定的解决方案:

public class URLParamEncoder {

    public static String encode(String input) {
        StringBuilder resultStr = new StringBuilder();
        for (char ch : input.toCharArray()) {
            if (isUnsafe(ch)) {
                resultStr.append('%');
                resultStr.append(toHex(ch / 16));
                resultStr.append(toHex(ch % 16));
            } else {
                resultStr.append(ch);
            }
        }
        return resultStr.toString();
    }

    private static char toHex(int ch) {
        return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
    }

    private static boolean isUnsafe(char ch) {
        if (ch > 128 || ch < 0)
            return true;
        return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
    }

}

我阅读了以前的答案,写我自己的方法,因为我不能有一些正确的工作使用以前的答案的解决方案,它看起来对我很好,但如果你能找到不与此工作的URL,请让我知道。

public static URL convertToURLEscapingIllegalCharacters(String toEscape) throws MalformedURLException, URISyntaxException {
            URL url = new URL(toEscape);
            URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
            //if a % is included in the toEscape string, it will be re-encoded to %25 and we don't want re-encoding, just encoding
            return new URL(uri.toString().replace("%25", "%"));
}

如果你用的是弹簧,你可以试试 org.springframework.web.util.UriUtils # encodePath

除了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中正确地传递到最终目的地。例如,您不能使用http://stackoverflow.com?url=http://yyy.com。UrlEncoding参数将修复该参数值。

所以我给你两个选择:

您是否有权访问与域分离的路径?如果是这样,您可以简单地对路径进行UrlEncode。然而,如果情况并非如此,那么选择2可能适合你。 commons - httpclient 3.1。它有一个类URIUtil: System.out.println(URIUtil.encodePath("http://example.com/x y", "ISO-8859-1"));

这将输出您正在寻找的内容,因为它只对URI的路径部分进行编码。

供您参考,这个方法需要common -codec和common -logging才能在运行时工作。