在Java中从相对URL构建绝对URL

19

我试图在不使用字符串技巧的情况下构建绝对URL,但遇到了困难...

假设有一个相对URL:

http://localhost:8080/myWebApp/someServlet

方法内部:

   public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}

构建的最“正确”方式是什么:

http://localhost:8080/myWebApp/someImage.jpg

(注意,必须是绝对路径,不能是相对路径)

目前,我通过构建字符串来实现,但肯定有更好的方法。

我尝试了多种新的URI / URL组合,但最终得到的结果是:

http://localhost:8080/someImage.jpg

非常感谢帮助


如果你不知道它是如何工作的,你怎么知道它是“真正简单的101东西”呢? - Bombe
这更多是对我的能力的贬低,而不是其他什么。然而,我已经编辑掉了这条评论,以防它被视为冒犯任何人 -- 这并不是我的意图。 - Marty Pitt
4个回答

44

使用 java.net.URL

 URL baseUrl = new URL("http://www.google.com/someFolder/");
 URL url = new URL(baseUrl, "../test.html");

1
做了这个之后,最终得到的仍然是相同的URL http://localhost:8080/someImage.jpg,而不是http://localhost:8080/myWebApp/someImage.jpg - lemoncodes
它还可以与以下代码一起使用:new URL(baseUrl, "/otherFolder/test.html"); 这将被翻译为:http://www.google.com/otherFolder/test.html - lepe
1
为了使 new URL(baseUrl, path) 正确解析,baseUrl 必须/ 结尾,而 path 必须 是相对路径(不以 / 开头)。此时...您可以简单地连接这些字符串,它同样有效,除非您还需要进行 ../ 处理。在那 一个 情况下,这种技术是有意义的。 - Clement Cherlin

4

如何:

String s = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/someImage.jpg";

1
如果我想在没有请求的情况下构建绝对URL,例如在调度程序线程中生成包含绝对URL链接的电子邮件,该怎么办? - Gelin Luo

1

看起来你已经解决了比较难的问题,也就是你正在使用什么主机。接下来的部分就容易了。

String url = host + request.getContextPath() + "/someImage.jpg";

应该会给你所需的。


-1

这段代码适用于Linux,它可以仅仅合并路径,如果你需要更多的功能,URI的构造函数可能会有所帮助。

URL baseUrl = new URL("http://example.com/first");
URL targetUrl = new URL(baseUrl, Paths.get(baseUrl.getPath(), "second", "/third", "//fourth//", "fifth").toString());

如果您的路径包含需要转义的内容,请首先使用URLEncoder.encode进行转义。
URL baseUrl = new URL("http://example.com/first");
URL targetUrl = new URL(baseUrl, Paths.get(baseUrl.getPath(), URLEncoder.encode(relativePath, StandardCharsets.UTF_8), URLEncoder.encode(filename, StandardCharsets.UTF_8)).toString());

例子:

import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
    public static void main(String[] args) {
        try {
            URL baseUrl = new URL("http://example.com/first");
            Path relativePath = Paths.get(baseUrl.getPath(), "second", "/third", "//fourth//", "fifth");
            URL targetUrl = new URL(baseUrl, relativePath.toString());
            System.out.println(targetUrl.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

输出

http://example.com/first/second/third/fourth/fifth

baseUrl.getPath()非常重要,不要忘记它。

一个错误的例子:

import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
    public static void main(String[] args) {
        try {
            URL baseUrl = new URL("http://example.com/first");
            Path relativePath = Paths.get("second", "/third", "//fourth//", "fifth");
            URL targetUrl = new URL(baseUrl, relativePath.toString());
            System.out.println(targetUrl.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

输出

http://example.com/second/third/fourth/fifth

我们在baseurl中失去了/first


Paths.get() 是一个文件系统 API。我刚刚检查了一下,它使用的是文件系统本地分隔符,在 Windows 上是 ""。 - Clement Cherlin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接