如何将URL编码为“可浏览”?

我想知道是否有任何方法可以解析这样的URL:

https://www.mysite.com/lot/of/unpleasant/folders/and/my/url with spaces &"others".xls 

 https://www.mysite.com/lot/of/unpleasant/folders/and/my/url%20with%20spaces%20&%22others%22.xls 

类似于Firefox在粘贴前URL时所做的URL重写,将其发送到服务器(除非您有这样的网站,否则无响应),然后从导航栏复制URL并将其粘贴到其他位置。

使用URLEncoder#encode给我这个(不需要的)输出:

 https%3A%2F%2Fwww.mysite.com%2Flot%2Fof%2Funpleasant%2Ffolders%2Fand%2Fmy%2Furl+with+spaces+%26%22others%22.xls 

遗憾的是,我收到一个字符串,如问题的开头所示,所以使用URLEncoder#encode直接不起作用。

我天真地试过这个:

 String evilUrl = "https://www.mysite.com/lot/of/unpleasant/folders/and/my/url with spaces &\"others\".xls"; URI uri = null; String[] urlParts = evilUrl.split("://"); String scheme = urlParts[0]; urlParts = urlParts[1].split("/"); String host = urlParts[0]; StringBuilder sb = new StringBuilder('/'); for (int i = 1; i < urlParts.length; i++) { sb.append('/'); sb.append(urlParts[i]); } uri = new URI(scheme, host, sb.toString(), null); System.out.println(uri.toASCIIString()); 

并给出这个(更好的)输出:

 https://www.mysite.com/lot/of/unpleasant/folders/and/my/url%20with%20spaces%20&%22others%22.xls 

但我不确定是否有一个开箱即用的解决方案来解决这个问题,而且我一无所获,或者如果我可以依赖这段代码几乎可以成功地解决我的问题。


顺便说一句,我已经访问过这个主题的一些资源:

  • 查询字符串参数的Java URL编码
  • Java中的HTTP URL地址编码
  • URLEncoder无法转换空格字符

这种url的问题在于它们是部分编码的,如果你尝试使用开箱即用的编码器,它将始终对整个字符串进行编码,所以我猜你使用自定义编码器的方法是正确的。 你的代码没问题,你只需要添加一些validation,例如,如果“邪恶url”不附带协议部分(即没有“https://”),除非你非常确定它永远不会发生。

我有一些空余时间所以我做了另一个自定义编码器,我遵循的策略是解析URL中不允许的字符并仅编码那些字符,而不是尝试重新编码整个事物:

 private static String encodeSemiEncoded(String semiEncondedUrl) { final String ALLOWED_CHAR = "!*'();:@&=+$,/?#[]-_.~"; StringBuilder encoded = new StringBuilder(); for(char ch: semiEncondedUrl.toCharArray()) { boolean shouldEncode = ALLOWED_CHAR.indexOf(ch) == -1 && !Character.isLetterOrDigit(ch) || ch > 127; if(shouldEncode) { encoded.append(String.format("%%%02X", (int)ch)); } else { encoded.append(ch); } } return encoded.toString(); } 

希望这可以帮助