【问题标题】:determine if a string is absolute URL or relative URL in java判断一个字符串是java中的绝对URL还是相对URL
【发布时间】:2011-05-22 09:44:48
【问题描述】:

给定一个字符串,我如何确定它是 Java 中的绝对 URL 还是相对 URL?我尝试了以下代码:

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

问题在于所有相对 URL(www.google.com/questions/ask)。正在抛出 MalformedURLException,因为没有定义协议。

【问题讨论】:

  • ... 所以你捕捉到异常返回false,说明相对URL其实不是绝对URL;这是预期的结果。那么这是怎么回事呢?
  • “www.google.com”和“/questions/ask”不是网址。它们可能是绝对或相对 URI,具体取决于隐含的 URL 方案。因此,此代码属于“按预期工作”的类别。
  • 注意 URL 使用您的网络连接
  • /file: 的绝对 URL,但它是 http: 的相对 URL。如果您不知道基本 URL(实际上是协议),则无法确定给定 URL 的相关性。在您的示例中 - www.google.com 是一个相对 URL,因此您的方法在这种情况下是正确且符合规范的,但它不能解决您的问题。

标签: java url relative-url


【解决方案1】:

这个怎么样:

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!");
}

更多信息here

【讨论】:

  • 这似乎不适用于Protocol Urls(网址如 //)。你可以try it out at IDEOne
  • 可以用来做绝对重定向,like in this example
  • 请注意,您仍然必须处理异常:URISyntaxException。它似乎并没有打扰 OP,但就我而言,我更喜欢真正的单线解决方案
  • @user1075613 URI.create
  • @Abhijit Sarkar 您应该将此作为答案发布(否则我会这样做:p)我会投票给您!
【解决方案2】:

正如我在my comment 中所说,您必须在检查 URL 之前对其进行规范化,并且规范化取决于您的应用程序,因为www.google.com 不是绝对 URL。这是一个示例代码,可用于检查 URL 是否是绝对的:

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

输出:

~$ 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

【讨论】:

    【解决方案3】:

    这是我用来确保链接是绝对链接的 sn-p:

    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
            }
        }
    }
    

    【讨论】:

    • 这不是一个正确的解决方案。 http/foo.html 是指向 html 子目录的相对 URL,但您的代码会认为它是绝对的。
    • 你的解决方案看起来像@StephenOstermiller?
    • 这里的其他答案使用URL.isAbsolute(),这对我来说似乎是一个很好的解决方案。
    【解决方案4】:

    我做了这个:

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

    【讨论】:

      猜你喜欢
      • 2012-05-28
      • 2011-04-29
      • 1970-01-01
      • 2021-06-22
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多