19

I'm having trouble building an absolute URL from a relative URL without resorting to String hackery...

Given

http://localhost:8080/myWebApp/someServlet

Inside the method:

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

What's the most "correct" way of building :

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

(Note, must be absolute, not relative)

Currently, I'm doing it through building the string, but there MUST be a better way.

I've looked at various combinations of new URI / URL, and I end up with

http://localhost:8080/someImage.jpg

Help greatly appreciated

Nathan
  • 8,093
  • 8
  • 50
  • 76
Marty Pitt
  • 28,822
  • 36
  • 122
  • 195
  • If you don’t know how it works, how do you know it’s “really simple 101 stuff”? – Bombe Sep 07 '09 at 12:33
  • It's more of a slur on my own ability than anything else. However, I've edited to remove the comment, in case it was perceived as offensive in anyway -- which was not the intent.) – Marty Pitt Sep 07 '09 at 12:37

4 Answers4

44

Using java.net.URL

 URL baseUrl = new URL("http://www.google.com/someFolder/");
 URL url = new URL(baseUrl, "../test.html");
Nathan Osman
  • 71,149
  • 71
  • 256
  • 361
Hamza Yerlikaya
  • 49,047
  • 44
  • 147
  • 241
  • 1
    did this, ended up with the same url `http://localhost:8080/someImage.jpg` instead of `http://localhost:8080/myWebApp/someImage.jpg` – lemoncodes Sep 15 '18 at 10:09
  • It also works with: `new URL(baseUrl, "/otherFolder/test.html");` which will translate into: `http://www.google.com/otherFolder/test.html` – lepe Mar 17 '20 at 04:30
  • 1
    In order for `new URL(baseUrl, path)` to resolve properly, `baseUrl` **must** end with `/` and `path` **must** be relative (not start with `/`). At that point...you could just append the strings and it would work equally well, unless you also need `../` processing. In that **one** case, this technique makes sense. – Clement Cherlin Mar 03 '22 at 15:03
4

How about:

String s = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/someImage.jpg";
JRL
  • 76,767
  • 18
  • 98
  • 146
  • 1
    What if I want to build the absolute URL in a context where no request is available, for example in a scheduler thread to generate email in which a absolute URL link is put – Gelin Luo Mar 19 '14 at 08:28
1

Looks like you already figured out the hard part, which is what host your are running on. The rest is easy,

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

Should give you what you need.

ZZ Coder
  • 74,484
  • 29
  • 137
  • 169
-1

this code work will on linux, it can just combine the path, if you want more, constructor of URI could be helpful.

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

if you path contain something need to escape, use URLEncoder.encode to escape it at first.

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());

example:

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();
        }
    }
}

output

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

baseUrl.getPath() are very important, don't forget it.

a wrong example:

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();
        }
    }
}

output

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

we have lost our /first in baseurl.

Forer
  • 17
  • 4