29 Stimmen

Bestimmen, ob ein String eine absolute URL oder eine relative URL in Java ist

Wie kann ich bei einer Zeichenkette feststellen, ob es sich um eine absolute oder relative URL in Java handelt? Ich habe den folgenden Code ausprobiert:

private boolean isAbsoluteURL(String urlString) {
    boolean result = false;
    try
    {
        URL url = new URL(urlString);
        String protocol = url.getProtocol();
        if (protocol != null && protocol.trim().length() > 0)
            result = true;
    }
    catch (MalformedURLException e)
    {
        return false;
    }
    return result;
}

Das Problem ist, dass alle relativen URLs ( www.google.com o /questions/ask ). werfen einen MalformedURLException weil kein Protokoll definiert ist.

2 Stimmen

... Sie fangen also die Ausnahme ab und geben false zurück, was darauf hinweist, dass die relative URL in Wirklichkeit keine absolute URL ist, was das erwartete Ergebnis ist. Inwiefern ist das also ein Problem?

0 Stimmen

"www.google.com" und "/questions/ask" sind keine URLs. Sie können absolute oder relative URIs sein, je nach dem impliziten URL-Schema. Dieser Code fällt also unter die Kategorie "funktioniert wie erwartet".

0 Stimmen

Beachten Sie, dass die URL Ihre Netzwerkverbindung nutzt

52voto

Chris Punkte 14839

Wie wäre es damit:

final URI u = new URI("http://www.anigota.com/start");
// URI u = new URI("/works/with/me/too");
// URI u = new URI("/can/../do/./more/../sophis?ticated=stuff+too");

if (u.isAbsolute())
{
  System.out.println("Yes, I am absolute!");
}
else
{
  System.out.println("Ohh noes, it's a relative URI!");
}

Mehr Infos aquí .

6 Stimmen

Dies scheint nicht zu funktionieren mit Protokoll Urls (Urls wie //). Sie können Probieren Sie es bei IDEOne aus

0 Stimmen

Die für absolute Umleitungen verwendet werden kann, wie in diesem Beispiel

0 Stimmen

Beachten Sie, dass Sie noch eine Ausnahme behandeln müssen: URISyntaxException. Es scheint OP nicht zu stören, aber in meinem Fall hätte ich eine echte Ein-Zeilen-Lösung bevorzugt

4voto

khachik Punkte 27252

Wie ich bereits in der mein Kommentar müssen Sie die URL normalisieren, bevor Sie sie überprüfen, und diese Normalisierung hängt von Ihrer Anwendung ab, da www.google.com ist keine absolute URL. Hier ist ein Beispielcode, der verwendet werden kann, um zu prüfen, ob URLs absolut sind:

import java.net.URL;

public class Test {
  public static void main(String [] args) throws Exception {
    String [] urls = {"www.google.com",
                      "http://www.google.com",
                      "/search",
                      "file:/dir/file",
                      "file://localhost/dir/file",
                      "file:///dir/file"};

    for (String url : urls) {
      System.out.println("`" + url + "' is " + 
                          (isAbsoluteURL(url)?"absolute":"relative"));
    }
  }

  public static boolean isAbsoluteURL(String url)
                          throws java.net.MalformedURLException {
    final URL baseHTTP = new URL("http://example.com");
    final URL baseFILE = new URL("file:///");
    URL frelative = new URL(baseFILE, url);
    URL hrelative = new URL(baseHTTP, url);
    System.err.println("DEBUG: file URL: " + frelative.toString());
    System.err.println("DEBUG: http URL: " + hrelative.toString());
    return frelative.equals(hrelative);
  }
}

Sortie :

~$ java Test 2>/dev/null
`www.google.com' is relative
`http://www.google.com' is absolute
`/search' is relative
`file:/dir/file' is absolute
`file://localhost/dir/file' is absolute
`file:///dir/file' is absolute

2voto

Renaud Punkte 15064

Dieses Snippet verwende ich, um sicherzustellen, dass die Links absolut sind:

private String ensureAbsoluteURL(String base, String maybeRelative) {
    if (maybeRelative.startsWith("http")) {
        return maybeRelative;
    } else {
        try {
           return new URL(new URL(base), maybeRelative).toExternalForm();
        } catch (MalformedURLException e) {
           // do something
        }
    }
}

1 Stimmen

Dies ist keine korrekte Lösung. http/foo.html ist eine relative URL, die auf die html Unterverzeichnis, aber Ihr Code würde denken, dass es absolut ist.

0 Stimmen

Wie würde Ihre Lösung aussehen, @StephenOstermiller?

1 Stimmen

Andere Antworten hier verwenden URL.isAbsolute() und das scheint mir eine gute Lösung zu sein.

1voto

Ufkoku Punkte 2264

Das habe ich gemacht:

public static String processUrl(String urlToProcess, String grantedNormalUrl){
    if (urlToProcess.startsWith("//")){
        urlToProcess = checkUrlStartsWithProtocol(urlToProcess);
        return urlToProcess;
    }

    if (!isAbsolute(urlToProcess)){
        String rootPage = extractRootPage(grantedNormalUrl);
        boolean domainEndsWithSlash = rootPage.endsWith("/");
        boolean urlStartsWithSlash = urlToProcess.startsWith("/");
        if (domainEndsWithSlash && urlStartsWithSlash){
            rootPage = rootPage.substring(0, rootPage.length() - 1); // exclude /
        }
        urlToProcess = rootPage + (!(domainEndsWithSlash || urlStartsWithSlash) ? "/" : "") + urlToProcess;
    }

    return urlToProcess;
}

public static boolean isAbsolute(String url){
    if (url.startsWith("//")) { // //www.domain.com/start
        return true;
    }

    if (url.startsWith("/")){ // /somePage.html
        return false;
    }

    boolean result = false;

    try {
        URI uri = new URI(url);
        result = uri.isAbsolute();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }

    return result;
}

public static String checkUrlStartsWithProtocol(String url) {
    if (!url.startsWith("http://") && !url.startsWith("https://")) {
        StringBuilder prefixBuilder = new StringBuilder();
        prefixBuilder.append("http:");
        if (!url.startsWith("//")) {
            prefixBuilder.append("//");
        }
        url = prefixBuilder.toString() + url;
    }
    return url;
}

public static String extractRootPage(String urlString) {
    int ignoreSlashes = 0;
    if (urlString.startsWith("http://") || urlString.startsWith("https://")) {
        ignoreSlashes = 2;
    }
    int endPosition = urlString.length();
    for (int i = 0; i < urlString.length(); i++) {
        if (urlString.charAt(i) == '/') {
            if (ignoreSlashes == 0) {
                endPosition = i; // substring exclude /
                break;
            } else {
                ignoreSlashes--;
            }
        }
    }
    return checkUrlStartsWithProtocol(urlString.substring(0, endPosition));
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X