【问题标题】:Extract base url from full url从完整网址中提取基本网址
【发布时间】:2020-02-04 19:56:09
【问题描述】:

有什么快速的方法可以从完整的 url 中提取 base url?例如,如果我有http://test.example.com/abcd/test.html - 我只想要http://test.example.com

我总是可以进行字符串解析 - 但想知道 Uri 中是否有可以直接获取的内容。

【问题讨论】:

  • 您所描述的不是基本网址。基本 URL 是在 HTML <base> Tag 中指定的 URL,它用作页面上所有 相对 链接的默认目标。

标签: android


【解决方案1】:

怎么样:

import java.net.URL;
import java.net.MalformedURLException;

try
{
  URL url = new URL("http://test.example.com/abcd/test.html");
  String baseUrl = url.getProtocol() + "://" + url.getHost();
}
catch (MalformedURLException e)
{
  // do something
}

【讨论】:

  • 工作正常,但抛出 java.net.MalformedURLException,我建议你使用正则表达式
  • 好吧,垃圾进,垃圾出。
  • 感谢 gnuf 和 Ondrej 的回答和 cmets。
  • @gnuf 您的方法适用于恰好以主机名结尾的基本 URL,但对于附加了附加路径的页面将失败。
  • 这里没有考虑端口
【解决方案2】:

java.net.URL doc 可以帮助您弄清楚如何“从完整网址中提取基本网址”

初步说明:

请注意来自URL javadoc page的这个重要提示

"注意,URI 类在某些情况下确实会对其组件字段进行转义。管理 URL 编码和解码的推荐方法是使用 URI,并使用 toURI() 和 @987654324 在这两个类之间进行转换@。”

自解释单元测试:

这里有 2 个简单的单元测试来说明“基本网址”的概念

package com.elementique.web;

import org.junit.Test;

import java.net.URI;
import java.net.URL;

import static org.junit.Assert.assertEquals;

public class UrlTest {

    @Test
    public void baseUrlAuthority() throws Exception {
        URL url = URI.create("http://username:password@host1:8080/directory/file?query#ref").toURL();

        assertEquals("http", url.getProtocol()); // protocol is also known as 'scheme'
        assertEquals("username:password@host1:8080", url.getAuthority());

        String baseUrlAuthority= url.getProtocol() + "://" + url.getAuthority();
        assert (url.toString().startsWith(baseUrlAuthority));
    }

    @Test
    public void baseUrlHostAndDefaultPort() throws Exception {
        URL url = URI.create("http://host2/a/b/c").toURL();

        assertEquals(-1, url.getPort()); // -1 as port is not defined in this case

        String baseUrlHostAndDefaultPort= url.getProtocol() + "://" + url.getHost();
        assert (url.toString().startsWith(baseUrlHostAndDefaultPort));
    }
}

提取基础网址:

所以,“从完整网址中提取基本网址”可以这样完成:

return url.getProtocol()+"://"+url.getAuthority()+"/"

或者这个,如果你不想要用户名/密码部分

if(url.getPort() == -1){ // port is not
    return url.getProtocol()+"://"+url.getHost()+"/";
} else {
    return url.getProtocol()+"://"+url.getHost()+":"+url.getPort()+"/";
} 

实施:

这是一个实现(基于 getAuthority() ):

public static String getBaseUrl(String urlString)
{

    if(urlString == null)
    {
        return null;
    }

    try
    {
        URL url = URI.create(urlString).toURL();
        return url.getProtocol() + "://" + url.getAuthority() + "/";
    }
    catch (Exception e)
    {
        return null;
    }
}

注意:
去掉尾随的“/”是你不想要的吗

【讨论】:

    【解决方案3】:

    Android URI 类中没有任何内容可以直接为您提供基本 URL - 正如 gnuf 建议的那样,您必须将其构建为协议 + getHost()。

    字符串解析方式可能更容易,并且可以避免将所有内容都塞入 try/catch 块中。只需获取 URL 的子字符串,从字符串开头到第三个“/”符号的所有内容。

    【讨论】:

    • 当然。但是你必须小心那些没有路径部分并且不包含可选的第三个/(RFC 1738,Sec 3.3 允许)的 URL。我想这取决于您是否相信传入的 URL 是有效的。
    猜你喜欢
    • 1970-01-01
    • 2012-09-24
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多