我想解决一些网址。为此,我得到了结果:
new URL(new URL(baseurl), link);
baseurl="http://www.site.com"
和link="./"
您将获得以下结果http://www.site.com/./
,而不只是http://www.site.com/
我该如何解决这个问题?
答案 0 :(得分:1)
也许这会有用吗?
new URI(baseUrl).resolve(link).toURL()
java.net.URI有一个解决方法,可能就是你要找的东西,而toURL则可以将它放到一个URL中。
修改强>
以下似乎对我有用..
import java.net.URL;
public class UrlTest {
private static URL resolve(URL base, String link) throws Exception {
if (base.getPath().isEmpty()) {
link = "/" + link;
}
URL u1 = base.toURI().resolve(link).normalize().toURL();
return u1;
}
private static void resolveUrls(URL baseUrl) throws Exception {
String link = "abcd";
String link2 = "./";
String link3 = "./foo";
System.out.println(resolve(baseUrl, link));
System.out.println(resolve(baseUrl, link2));
System.out.println(resolve(baseUrl, link3));
}
public static void main(String[] args) throws Exception {
String baseUrlStr = "http://www.somesite.com";
URL baseUrl = new URL(baseUrlStr);
resolveUrls(baseUrl);
baseUrl = new URL(baseUrlStr + "/index.html");
resolveUrls(baseUrl);
baseUrl = new URL(baseUrlStr + "/path/index.html");
resolveUrls(baseUrl);
}
}
答案 1 :(得分:1)
你可以试试这个
new URL(new URL(baseurl), link.replace("./"), "");
答案 2 :(得分:1)
import java.net.*;
class TestURL {
public static void main(String[] args) throws Exception {
String s = "http://www.site.com/./";
URL url = new URL(s);
System.out.println(url);
URI uri = url.toURI();
System.out.println(uri.normalize().toURL());
}
}
http://www.site.com/./
http://www.site.com/
答案 3 :(得分:1)
这是一个非常长的,虽然信息丰富,但在很大程度上无益的帖子,但最后确实有一个答案。
这是一个悲伤的故事。这显然很疯狂:
URI base = new URI("http", "example.org", null, null);
URI link = new URI(null, null, "index.html", null);
System.out.println(base.resolve(link));
应打印:
http://example.orgindex.html
而不是:
http://example.org/index.html
然而确实如此。为什么?因为java.net.URI
...
表示由RFC 2396定义的URI引用:统一资源标识符(URI):通用语法
忠诚地这样做。特别是resolve
方法......
以符合RFC 2396 section 5.2
的方式构造新的分层URI
可悲的是,5.2节中指定的算法是错误的。具体来说,尽管它说......
路径组件永远不会被定义,尽管它可能是空的
它不能确保针对具有空路径的基URI解析相对URI的结果是有效的URI。问题在于步骤6,该步骤涉及将来自基础和相对URI的路径合并到将用于形成已解析URI的缓冲区中。第6步的前两个子步骤是:
a)基URI的路径组件的最后一段除了复制到缓冲区外。换句话说,排除最后一个(最右边)斜杠字符后的任何字符(如果有)。
b)引用的路径组件被附加到缓冲区字符串。
如果基URI具有空路径,则在子步骤a之后,缓冲区将为空。如果相对URI的路径不以/开头,那么在子步骤b之后,缓冲区将包含一个不以/开头的字符串。以下步骤处理点标准化,并且无需添加前导/。最后一步是:
h)剩余的缓冲区字符串是引用URI的新路径组件。
因此,已解析的URI有一个不以/开头的路径。然后,步骤7将其构建为已解析URI的最终字符串形式,而无需插入/的任何规定。因此,在没有前导/反对具有空路径的基URI的情况下解析相对URI会导致无意义。这是RFC 2396指定的内容,以及java.net.URI
的内容。
糟糕!
这个故事并没有完全结束。 2005年1月,RFC 3986发布。这已废弃的RFC 2396,并在section 5.2中包含URI解析的新定义。这个定义完全以更严格(或至少看起来很严谨)的方式重写,并指定section 5.2.3中路径的合并,这是从正确的方向开始的:
如果基URI具有已定义的权限组件和空路径,则返回由与引用的路径连接的“/”组成的字符串
因此,如果更新Java以符合一个已有八年历史的RFC而不是一个十四岁的RFC,那么整个问题就会得到解决。这样做是bug 6791060所要求的,它于2009年开放,最后一次触及2010年。太阳,我很失望。
无论如何,有了这种理解,我们可以看到正确的解决方案是这样的:
public static URI fix(URI uri) {
if (uri.getPath().isEmpty()) {
try {
return new URI(uri.getScheme(), uri.getAuthority(), "/", uri.getQuery(), uri.getFragment());
}
catch (URISyntaxException e) {
AssertionError ae = new AssertionError("highly implausible error fixing URI " + uri);
ae.initCause(e);
throw ae;
}
}
else {
return uri;
}
}
fix(new URI(baseurl)).resolve(link);