我在我的Android应用程序中使用HttpClient。在某些时候,我必须从远程位置获取数据。下面是我如何利用HttpClient获取响应的片段。
String url_s = "https://mydomain.com/abc/{5D/{B0blhahblah-blah}I1.jpg"; //my url string
DefaultHttpClient httpClient = new DefaultHttpClient();
response = httpClient.execute(new HttpGet(url_s));
它在大多数情况下都能正常工作,但在我的网址中基本上是字符串时有一些花括号。堆栈跟踪向我显示花括号的索引,其中包含无效字符。 所以我尝试从编码的URL创建URI。
URL url = new URL(url_s);
URI uri = url.toURI();
response = httpClient.execute(new HttpGet(uri));
这样做后,我根本没有从远程位置得到结果。我解决了这个问题并通过替换大括号来修复它
但我对我的解决方案并不完全满意。还有更好的解决方案吗?有什么东西整洁而不像我的那样硬编码?
答案 0 :(得分:10)
严格的答案是,您的网址中不应该有大括号
有效网址的完整说明可在RFC1738
中找到这个答案的相关部分如下
不安全:
由于多种原因,角色可能不安全。空间
角色是不安全的,因为重要的空间可能会消失 URL转录时可能会引入微不足道的空格 排版或接受文字处理程序的处理 字符“<”和“>”是不安全的,因为它们被用作
自由文本中的URL分隔符;引号(“”“)用于表示 在某些系统中划分URL。字符“#”是不安全的,应该 总是被编码,因为它在万维网和其他用途中使用 用于从可能的片段/锚标识符界定URL的系统 跟着它。字符“%”不安全,因为它用于
其他角色的编码。其他角色不安全因为
已知网关和其他运输代理有时会修改 这样的人物。这些字符是“{”,“}”,“|”,“\”,“^”,“〜”,
“[”,“]”和“`”。所有不安全的字符必须始终在URL中编码。对于
例如,即使在中,字符“#”也必须在URL中编码 通常不处理碎片或锚的系统
标识符,以便如果将URL复制到另一个系统中 确实使用它们,没有必要更改URL编码。
为了绕过您遇到的问题,您必须对您的网址进行编码。
当整个网址被编码包括https://mydomain.com/部分时,您遇到的“主机可能不为空”错误会发生错误,因此会感到困惑。您只想编码名为路径的URL的最后一部分。
解决方案是使用Uri.Builder类从应该对进程中的路径进行编码的各个部分构建URI
您可以在Android SDK Uri.Builder reference documentation
中找到详细说明使用您的值的一些简单示例是:
Uri.Builder b = Uri.parse("https://mydomain.com").buildUpon();
b.path("/abc/{5D/{B0blhahblah-blah}I1.jpg");
Uri u = b.build();
或者您可以使用链接:
Uri u = Uri.parse("https://mydomain.com").buildUpon().path("/abc/{5D/{B0blhahblah-blah}I1.jpg").build();
答案 1 :(得分:1)
除非RFC1738已经过时十多年,否则已被rfc3986取代,并且没有迹象表明:
https://tools.ietf.org/html/rfc3986
花括号是不安全的(实际上,RFC在任何地方都不包含单个花括号字符)。此外,我在包含大括号的浏览器中尝试过URI,它们工作正常。
另请注意,OP正在使用一个名为URI的类 - 如果不是3987,它肯定应该遵循3986。
然而,奇怪的是,IRI定义于:
https://tools.ietf.org/html/rfc3987
请注意:
接受IRI的系统也可以处理可打印的字符 在URI中不允许的US-ASCII,即“<”,“>”,“”, 在上面的步骤2中,空格,“{”,“}”,“|”,“\”,“^”和“`”。如果这些 找到字符但未转换,然后转换
应该失败。请注意数字符号(“#”),百分比
符号(“%”)和方括号字符(“[”,“]”)不是一部分 以上列表并且不得转换。
换句话说,看起来RFC本身存在一些问题。