Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将相对URL追加到java.net.URL_Java_Url - Fatal编程技术网

将相对URL追加到java.net.URL

将相对URL追加到java.net.URL,java,url,Java,Url,假设我有一个java.net.URL对象,指向 http://example.com/myItems或http://example.com/myItems/ 是否有某个帮助程序可以将某个相对URL附加到此文件? 例如,追加/myItemId或myItemId以获取: http://example.com/myItems/myItemIdURL有一个以URL和String规范为基础的 或者,java.net.URI更符合标准,并且有一种方法来做同样的事情。用你的URL创建一个URI。我已经到处搜索

假设我有一个java.net.URL对象,指向

http://example.com/myItems
http://example.com/myItems/

是否有某个帮助程序可以将某个相对URL附加到此文件? 例如,追加
/myItemId
myItemId
以获取:
http://example.com/myItems/myItemId

URL
有一个以
URL
String
规范为基础的


或者,
java.net.URI
更符合标准,并且有一种方法来做同样的事情。用你的
URL
创建一个
URI

我已经到处搜索了这个问题的答案。我能找到的唯一实现是Android SDK:。我提取它是为了我自己的目的

private String appendSegmentToPath(String path, String segment) {
  if (path == null || path.isEmpty()) {
    return "/" + segment;
  }

  if (path.charAt(path.length() - 1) == '/') {
    return path + segment;
  }

  return path + "/" + segment;
}
就是我找到源头的地方


结合,我使用它的方式如下:
builder.setPath(appendSegmentToPath(builder.getPath(),segment))

使用Apache URIBuilder的一些示例:

例1:

结果1->

例2:


结果2->

基于twhitbeck答案的我的解决方案:

import java.net.URI;
import java.net.URISyntaxException;

public class URIBuilder extends org.apache.http.client.utils.URIBuilder {
    public URIBuilder() {
    }

    public URIBuilder(String string) throws URISyntaxException {
        super(string);
    }

    public URIBuilder(URI uri) {
        super(uri);
    }

    public org.apache.http.client.utils.URIBuilder addPath(String subPath) {
        if (subPath == null || subPath.isEmpty() || "/".equals(subPath)) {
            return this;
        }
        return setPath(appendSegmentToPath(getPath(), subPath));
    }

    private String appendSegmentToPath(String path, String segment) {
        if (path == null || path.isEmpty()) {
            path = "/";
        }

        if (path.charAt(path.length() - 1) == '/' || segment.startsWith("/")) {
            return path + segment;
        }

        return path + "/" + segment;
    }
}
测试:


要点:

此操作不需要任何额外的lib或代码,并提供所需的结果:

//import java.net.URL;
URL url1 = new URL("http://petstore.swagger.wordnik.com/api/api-docs?foo=1&bar=baz");
URL url2 = new URL(url1.getProtocol(), url1.getHost(), url1.getPort(), url1.getPath() + "/pet" + "?" + url1.getQuery(), null);
System.out.println(url1);
System.out.println(url2);
这张照片是:

http://petstore.swagger.wordnik.com/api/api-docs?foo=1&bar=baz
http://petstore.swagger.wordnik.com/api/api-docs/pet?foo=1&bar=baz

只有在主机后面没有路径时,接受的答案才有效(我知道接受的答案是错误的)

我编写了一个帮助函数来添加到url路径:

public static URL concatenate(URL baseUrl, String extraPath) throws URISyntaxException, 
                                                                    MalformedURLException {
    URI uri = baseUrl.toURI();
    String newPath = uri.getPath() + '/' + extraPath;
    URI newUri = uri.resolve(newPath);
    return newUri.toURL();
}

已更新

我相信这是最短的解决方案:

URL url1 = new URL("http://domain.com/contextpath");
String relativePath = "/additional/relative/path";
URL concatenatedUrl = new URL(url1.toExternalForm() + relativePath);
您可以使用和方法
URI#normalize
,以避免URI中重复的
/

URIBuilder uriBuilder = new URIBuilder("http://example.com/test");
URI uri = uriBuilder.setPath(uriBuilder.getPath() + "/path/to/add")
          .build()
          .normalize();
// expected : http://example.com/test/path/to/add

对于android,请确保使用来自android.net.Uri的
.appendPath()

将相对路径连接到Uri:

java.net.URI uri = URI.create("https://stackoverflow.com/questions")
java.net.URI res = uri.resolve(uri.getPath + "/some/path")

res
将包含
https://stackoverflow.com/questions/some/path

您只需使用
URI
类即可:

import java.net.URI;
import org.apache.http.client.utils.URIBuilder;

URI uri = URI.create("http://example.com/basepath/");
URI uri2 = uri.resolve("./relative");
// => http://example.com/basepath/relative
请注意基本路径上的尾随斜杠和所附加段的基本相对格式。您还可以使用Apache HTTP客户端的
URIBuilder
类:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

我对URI的编码有一些困难。追加对我来说不起作用,因为它是content://类型,并且不喜欢“/”。此解决方案假设没有查询,也没有片段(毕竟我们正在处理路径):

科特林代码:

  val newUri = Uri.parse(myUri.toString() + Uri.encode("/$relPath"))
在Android上你可以使用。下面允许从现有URL创建
Uri.Builder
,作为
String
,然后追加:

Uri.parse(baseUrl) // Create Uri from String
    .buildUpon()   // Creates a "Builder"
    .appendEncodedPath("path/to/add")
    .appendQueryParameter("at_ref", "123") // To add ?at_ref=123
    .fragment("anker") // To add #anker
    .build()
请注意,
appendEncodedPath
不需要前导的
/
,只包含检查“baseUrl”是否以一结尾,否则在路径之前添加一个

根据文档,这支持

  • 遵循模式的绝对层次URI引用

    • ://?#
  • 带模式的相对URI

    • ?#
    • /?#
  • 带模式的不透明URI

    • :#

下面给出了一个没有任何外部LIB的实用解决方案

(评论:在阅读了迄今为止给出的所有答案后,我真的对提供的解决方案不满意——特别是这个问题已经八年了。没有任何解决方案能够正确处理查询、片段等。)

URL上的扩展方法 测试

可能的重复似乎没有简单的解决方案。URL或URI类都不支持此操作。Apache HttpClient也不支持此功能。
newURL(“/additional/relative/path”)抛出MalformedURLException“URL具有接受基本URL和字符串规范的构造函数”-没有帮助。URL url1=newurl(“);URL url2=newurl(url1,“/pet”);System.out.println(url2.toString())为您提供了:,这不是为了其他人的利益:第一个URL构造函数方法的工作方式与我预期的不完全一样(rtfm,呃?)。仅使用baseURL的非路径部分。@user2585038:第二个参数不能以斜杠开头。斜杠表示“绝对”“链接,因此url1的路径被丢弃。URI解析实际上只在这里错误地起作用。请参阅belowAs@user2585038中@Christoph Henkelmann的回答。该回答没有考虑第5.2(6a)节,该节规定:“除了基本URI路径组件的最后一段之外,所有其他段都复制到缓冲区。换句话说,最后(最右边)斜杠字符(如果有)之后的任何字符都被排除在外。”这个IMO使得URI解析在大多数情况下都不可用,包括OP的情况。
MalformedUrlException
为什么他们不抛出未经检查的异常:'(是的,这很糟糕……而且不一致:解析数字会引发未经检查的异常^^^此解决方案不处理尾部斜杠。问题提供了两个示例。
url1.getFile().endsWith(“/”)?url1.getFile()+“pet”:url1.getFile()+“/pet”
?@Martinsene发现得很好,我对示例进行了调整。使用jersey客户端的UriBuilder/If
baseUrl
/
结尾或
外部路径
/
开头,您将在最终URL中重复
/
。您应该添加
.normalize()
在最后一次
toul()之前
。这不适用于以开头的本地文件URLfile://If 运行此代码后,我想您会发现结果是:更正了使用
uri.getPath
的代码,谢谢!第一位代码的结果不是
http://example.com/basepath/relative
,但
http://example.com/relative
,未经修订单独地使这个答案的第一部分不正确。事实上,答案的第一部分是正确的;如果在第一个URI中有多个/,那么如果没有提供./也会起作用~~~
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>
import java.net.URI;
import org.apache.http.client.utils.URIBuilder;

URI uri = URI.create("http://example.com/basepath");
URI uri2 = appendPath(uri, "relative");
// => http://example.com/basepath/relative

public URI appendPath(URI uri, String path) {
    URIBuilder builder = new URIBuilder(uri);
    builder.setPath(URI.create(builder.getPath() + "/").resolve("./" + path).getPath());
    return builder.build();
}
  val newUri = Uri.parse(myUri.toString() + Uri.encode("/$relPath"))
Uri.parse(baseUrl) // Create Uri from String
    .buildUpon()   // Creates a "Builder"
    .appendEncodedPath("path/to/add")
    .appendQueryParameter("at_ref", "123") // To add ?at_ref=123
    .fragment("anker") // To add #anker
    .build()
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

class URLHelper {
        public static URL appendRelativePathToURL(URL base, String relPath) {
            /*
              foo://example.com:8042/over/there?name=ferret#nose
              \_/   \______________/\_________/ \_________/ \__/
               |           |            |            |        |
            scheme     authority       path        query   fragment
               |   _____________________|__
              / \ /                        \
              urn:example:animal:ferret:nose

            see https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
            */
            try {

                URI baseUri = base.toURI();

                // cut initial slash of relative path
                String relPathToAdd = relPath.startsWith("/") ? relPath.substring(1) : relPath;

                // cut trailing slash of present path
                String path = baseUri.getPath();
                String pathWithoutTrailingSlash = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;

                return new URI(baseUri.getScheme(),
                        baseUri.getAuthority(),
                        pathWithoutTrailingSlash + "/" + relPathToAdd,
                        baseUri.getQuery(),
                        baseUri.getFragment()).toURL();
            } catch (URISyntaxException e) {
                throw new MalformedURLRuntimeException("Error parsing URI.", e);
            } catch (MalformedURLException e) {
                throw new MalformedURLRuntimeException("Malformed URL.", e);
            }
        }

        public static class MalformedURLRuntimeException extends RuntimeException {
            public MalformedURLRuntimeException(String msg, Throwable cause) {
                super("Malformed URL: " + msg, cause);
            }
        }
    }
    private void demo() {

        try {
            URL coolURL = new URL("http://fun.de/path/a/b/c?query&another=3#asdf");
            URL notSoCoolURL = new URL("http://fun.de/path/a/b/c/?query&another=3#asdf");
            System.out.println(URLHelper.appendRelativePathToURL(coolURL, "d"));
            System.out.println(URLHelper.appendRelativePathToURL(coolURL, "/d"));
            System.out.println(URLHelper.appendRelativePathToURL(notSoCoolURL, "d"));
            System.out.println(URLHelper.appendRelativePathToURL(notSoCoolURL, "/d"));

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }