我正在为我的 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 中有一些花括号(基本上是字符串)时就不行了。堆栈跟踪向我显示了大括号的索引,显示“无效字符”。
所以我尝试从编码的 URL 创建 URI。
URL url = new URL(url_s);
URI uri = url.toURI();
response = httpClient.execute(new HttpGet(uri));
这样做之后,我根本没有从远程位置得到结果。我解决了这个问题,并通过将大括号
来修复它,但我对我的解决方案并不完全满意。还有更好的解决方案吗?有什么像我这样整洁而不是硬编码的吗?
I am using HttpClient for my android application. At some point, I have to fetch data from remote locations. Below is the snippet how I made use of HttpClient to get the response.
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));
It works absolutely fine in most cases but not when there is some curly braces in my url which is String basically. The stack trace shows me the index of curly braces saying Invalid character.
So I tried to create URI from encoded URL.
URL url = new URL(url_s);
URI uri = url.toURI();
response = httpClient.execute(new HttpGet(uri));
After doing so, i didn't get the result from remote location at all. I worked around the problem and fixed it by replacing the curly brace
- "{" with "%7B"
- "}" with "%7D"
But I am not totally satisfy with my solution. Are there any better solutions? Anything neat and not hard-coded like mine?
发布评论
评论(2)
严格的答案是,您的 URL 中不应包含大括号。
有效 URL 的完整说明可以在 RFC1738
该答案的相关部分如下
为了绕过您遇到的问题,您必须对您的网址进行编码。
当整个网址(包括 https://mydomain 进行编码时,您遇到的“主机可能不为空”错误的问题将会发生) .com/ 部分,因此会变得混乱。您只想对 URL 的最后部分(称为路径)进行编码。
解决方案是使用 Uri.Builder 类从各个部分构建 URI,这些部分应在过程中对路径进行编码。
您将在 Android SDK Uri.Builder 参考文档
使用您的值的一些简单示例是:
或者您可以使用链接:
The strict answer is that you should never have curly braces in your URL
A full description of valid URL's can be found in RFC1738
The pertinent part for this answer is as follows
In order to bypass the problem you have been experiencing you must encode your url.
The problem you experienced with the "host may not be null" error will happen when the entire url is being encoded including the https://mydomain.com/ part so it gets confused. You only want to encode the last part of the URL called the path.
The solution is to use the Uri.Builder class to build your URI from the individual parts which should encode the path in the process
You will find a detailed description in the Android SDK Uri.Builder reference documentation
Some trivial examples using your values are:
Or you can use chaining:
除了 RFC1738 已经过时十多年,已被 rfc3986 取代,并且没有任何指示:
https://www.rfc-editor.org/rfc/rfc3986
大括号是不安全的(在事实上,RFC 在任何地方都不包含单个大括号字符)。此外,我已经在包含花括号的浏览器中尝试过 URI,并且它们工作得很好。
另请注意,OP正在使用一个名为URI的类 - 它绝对应该遵循3986,至少,如果不是3987的话。
然而,奇怪的是,IRIs定义在:
https://www.rfc-editor.org/rfc/rfc3987
有注释:
换句话说,RFC 本身似乎存在一些问题。
Except RFC1738 has been obsolete for over a decade, has been superseded by rfc3986 and there is no indication in:
https://www.rfc-editor.org/rfc/rfc3986
That curly braces are unsafe (In fact, the RFC does not contain a single curly brace character anywhere). Furthermore, I've tried URI's in browsers that contain curly braces, and they work fine.
Also note the OP is using a class called URI - which should definitely be following 3986, at the very least, if not 3987.
However, oddly, IRIs defined in:
https://www.rfc-editor.org/rfc/rfc3987
Have the note that:
In other words, it looks like the RFCs themselves have some issues.