如何使用Java从相对URL构建绝对URL?

时间:2018-03-06 12:33:43

标签: java http url

我有一个相对的url字符串,知道主机和协议。如何构建绝对url字符串?

好像很容易?是的,一开始看,但直到逃脱的角色来。我必须从302代码http(s)响应位置标题构建绝对URL。

让我们考虑一个例子

protocol: http
host: example.com
location: /path/path?param1=param1Data&param2= " 

首先我尝试构建url字符串,如:

Sting urlString = protocol+host+location

URL类的构造函数不会转义空格和双引号:

new URL(urlString)

URI类的构造函数失败,异常:

new URI(urlString)

URI.resolve方法也失败,异常

然后我发现URI可以在查询字符串中转义params,但只有很少的构造函数,比如:

URI uri = new URI("http", "example.com", 
    "/path/path", "param1=param1Data&param2= \"", null);

此构造函数需要路径和查询是一个单独的参数,但我有一个相对URL ,它不会被路径和查询部分拆分。

我可以考虑检查相对网址是否包含“?”问题标志并认为它之前的一切都是路径,并且它之后的所有内容都是查询,但是如果相对网址不包含路径,但仅查询,并且查询包含“?”标志?然后这将无效,因为部分查询将被视为路径。

现在我无法了解如何从相对网址构建绝对网址。

这些被接受的答案似乎错了:

考虑相关url与主机和某个路径部分的url相关的情况可能会很好:

初始网址http://example.com/...some路径... 相对/home?...query here ...

获得java核心解决方案会很棒,尽管仍然可以使用一个好的lib。

2 个答案:

答案 0 :(得分:5)

第一个?表示查询字符串的开始位置:

  

3.4. Query

     

[...]查询组件由第一个问号(?)字符表示,并以数字符号(#)字符或URI结尾终止。

一种简单的方法(不会处理片段并假设查询字符串始终存在)非常简单:

String protocol = "http";
String host = "example.com";
String location = "/path/path?key1=value1&key2=value2";

String path = location.substring(0, location.indexOf("?"));
String query = location.substring(location.indexOf("?") + 1);

URI uri = new URI(protocol, host, path, query, null);

可以处理片段的更好方法可以是:

String protocol = "http";
String host = "example.com";
String location = "/path/path?key1=value1&key2=value2#fragment";

// Split the location without removing the delimiters
String[] parts = location.split("(?=\\?)|(?=#)");

String path = null;
String query = null;
String fragment = null;

// Iterate over the parts to find path, query and fragment
for (String part : parts) {

    // The query string starts with ?
    if (part.startsWith("?")) {
        query = part.substring(1); 
        continue;
    }

    // The fragment starts with #
    if (part.startsWith("#")) {
        fragment = part.substring(1);
        continue;
    }

    // Path is what's left
    path = part;
}

URI uri = new URI(protocol, host, path, query, fragment);

答案 1 :(得分:0)

最好的方法似乎是使用多件构造函数创建一个URI对象,然后将其转换为如下所示的URL:

URI uri = new URI("https", "sitename.domain.tld", "/path/goes/here", "param1=value&param2=otherValue");
URL url = uri.toURL();