在Java中,如何在URL / URI中对默认vhost%2F进行编码,以便它不会被更改为斜杠并且无法工作

时间:2015-11-24 05:25:15

标签: java rabbitmq

要使用admin API,默认的vhost" /"必须根据文档编译为%2F:2nd paragraph, here

我很难得到java.net.URI类 - 正如大多数任何http请求的东西(例如org.apache.http.client.methods.HttpRequestBase)所使用的那样 - 发出该表单的字符串。

即,我希望new URI("http", null, "localhost", 8080, "/api/exchanges/%2F", "", null).toASCIIString()http://localhost:8080/api/exchanges/%2F?,但不是http://localhost:8080/api/exchanges/%252F?

如果路径是/api/exchanges//(双斜杠,其中第二个斜杠应该是默认的vhost,这是错误的,但没关系),那么结果是http://localhost:8800/api/exchanges//?(没有&# 39;使用RabbitMQ管理服务,它认为它是http://localhost:8800/api/exchanges/(一个斜杠),然后返回所有虚拟主机上的所有交换。

那么,秘诀是什么?

(顺便说一句,this question不是一个骗局:它只是从一个File开始,它真的应该具有路径中的" /"的专业知识。我在这里只谈简单的Jane URI。)

仅供参考,代码墙TestNG测试显示各种排列 - 这些测试都传递,这表明我无法以这种方式获得%2F

package com.bakins_bits;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import org.testng.annotations.Test;

public class TestSingleSlashURIPaths
{
    @Test(enabled = true)
    public void does_URI_or_URL_mangle_single_slash_paths_example_1()
        throws MalformedURLException, UnsupportedEncodingException, URISyntaxException {
        // ARRANGE
        String sut = "http://localhost:8800/api/exchanges//";

        // ACT
        URL url = new URL(sut);
        String path = "/api/exchanges//";
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), path, "", url.getRef());
        String result = uri.toURL().toString();

        // ASSERT
        assertThat(url.toString()).isEqualTo("http://localhost:8800/api/exchanges//");
        assertThat(uri.getPath()).isEqualTo("/api/exchanges//");
        assertThat(uri.toString()).isEqualTo("http://localhost:8800/api/exchanges//?");
        assertThat(uri.toASCIIString()).isEqualTo("http://localhost:8800/api/exchanges//?");
        assertThat(result).isEqualTo("http://localhost:8800/api/exchanges//?");
    }

    @Test(enabled = true)
    public void does_URI_or_URL_mangle_single_slash_paths_example_2()
        throws MalformedURLException, UnsupportedEncodingException, URISyntaxException {
        // ARRANGE
        String sut = "http://localhost:8800/api/exchanges/%2F";

        // ACT
        URL url = new URL(sut);
        String path = "/api/exchanges/%2F";
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), path, "", url.getRef());
        String result = uri.toURL().toString();

        // ASSERT
        assertThat(url.toString()).isEqualTo("http://localhost:8800/api/exchanges/%2F");
        assertThat(uri.getPath()).isEqualTo("/api/exchanges/%2F");
        assertThat(uri.toString()).isEqualTo("http://localhost:8800/api/exchanges/%252F?");
        assertThat(uri.toASCIIString()).isEqualTo("http://localhost:8800/api/exchanges/%252F?");
        assertThat(result).isEqualTo("http://localhost:8800/api/exchanges/%252F?");
    }

    @Test(enabled = true)
    public void does_URI_or_URL_mangle_single_slash_paths_example_3()
        throws MalformedURLException, UnsupportedEncodingException, URISyntaxException {
        // ARRANGE
        String sut = "http://localhost:8800/api/exchanges/%252F";

        // ACT
        URL url = new URL(sut);
        String path = "/api/exchanges/%252F"; // try pre-encoding the '%'
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), path, "", url.getRef());
        String result = uri.toURL().toString();

        // ASSERT
        assertThat(url.toString()).isEqualTo("http://localhost:8800/api/exchanges/%252F");
        assertThat(uri.getPath()).isEqualTo("/api/exchanges/%252F");
        assertThat(uri.toString()).isEqualTo("http://localhost:8800/api/exchanges/%25252F?");
        assertThat(uri.toASCIIString()).isEqualTo("http://localhost:8800/api/exchanges/%25252F?");
        assertThat(result).isEqualTo("http://localhost:8800/api/exchanges/%25252F?");
    }
}

1 个答案:

答案 0 :(得分:0)

魅力。 @ dave_thompson_085和@Suboptimal在上面的评论中给出了答案(不确定如何给予他们代表信用,因为那些不是答案)。 (我正在遭受一点隧道视觉,并没有亲自尝试。)

问题显然在构造函数URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)中,因为构造函数URI(String str)有效。

请注意,即使在这种情况下(请参阅下面的测试)URI::getPath()也不会返回%2F您所期望的(因为那是您的输入),而是/

然而我很高兴,因为这意味着问题可以在我正在使用的客户端库中解决(使用7参数构造函数,而不是1参数构造函数)。所以我会在那里提交一个bug。 (不幸的是,该库中具有此构造函数调用的方法是private static在一个辅助类中,在另一个静态方法中调用它(并放入一个被消耗的数据结构中),因此没有简单/明显的运行时补丁我可以(通过,例如,继承)。我讨厌实用程序类。我将构建我自己的这个库的副本来修复它。)

谢谢!

    @Test(enabled = true)
    public void does_URI_or_URL_mangle_single_slash_paths_example_4()
        throws MalformedURLException, UnsupportedEncodingException, URISyntaxException {
        // ARRANGE
        String sut = "http://localhost:8800/api/exchanges/%2F?";

        // ACT
        URI uri = new URI(sut);
        String result = uri.toURL().toString();

        // ASSERT
        assertThat(uri.getPath()).isEqualTo("/api/exchanges//"); // <== this seems wrong!
        assertThat(uri.toString()).isEqualTo("http://localhost:8800/api/exchanges/%2F?");
        assertThat(uri.toASCIIString()).isEqualTo("http://localhost:8800/api/exchanges/%2F?");
    }