java 当 URL 包含“]”时,使用 URL.getPort() 提取端口号时出现问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4839447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Problem extracting port number with URL.getPort() when URL contains "]"
提问by Mike Lowery
I'm using java.net.URL.getPort() to extract the port number from a URL. Most of the time this works great. However, when the URL contains a right bracket character "]" it fails:
我正在使用 java.net.URL.getPort() 从 URL 中提取端口号。大多数时候这很好用。但是,当 URL 包含右括号字符“]”时,它会失败:
new URL("http://abc.com:123/abc.mp3").getPort();
returns: (int) 123
But if the URL contains "]" I get:
但如果 URL 包含“]”,我会得到:
new URL("http://abc.com:123/abc].mp3").getPort();
returns: (int) -1
What am I doing wrong?
我究竟做错了什么?
EDIT #1: As a test, I pasted this same code into a non-Android Java app and the port number was correctly returned, so this appears to be an anomaly with the Android SDK.
编辑 #1:作为测试,我将此相同的代码粘贴到非 Android Java 应用程序中,并且正确返回了端口号,因此这似乎是 Android SDK 的异常情况。
回答by Jonas
If your URL contains some symbols that are not valid in URLs, you have to use an URL-encoded String. They way to do it in Java seem to be by using URI
.
如果您的 URL 包含一些在 URL 中无效的符号,则必须使用 URL 编码的字符串。他们在 Java 中的实现方式似乎是使用URI
.
new URI( "http", null, "abc.com", 123, "abc].mp3", null, null).toURL().getPort();
If you already has an URL string:
如果您已经有一个 URL 字符串:
URL url = new URL("http://abc.com:123/abc].mp3");
Then this works for me:
然后这对我有用:
new URI(
url.getProtocol(),
null,
url.getHost(),
url.getPort(),
url.getPath(),
null,
null);
But then again I'm using url.getPort()
that you said didn't work. But when I'm testing on Java 6 now. new URL("http://abc.com:123/abc].mp3").getPort();
actually works for me, maybe it's just on Android it doesn't work? In case it doesn't work I think it's best to use a third party library for this. Apache Http Client that is included in Android seem to have some extra functionality for URLs: see org.apache.http.client.utils
但话又说回来,我正在使用url.getPort()
你说的不起作用。但是当我现在在 Java 6 上进行测试时。new URL("http://abc.com:123/abc].mp3").getPort();
实际上对我有用,也许它只是在 Android 上不起作用?如果它不起作用,我认为最好为此使用第三方库。Android 中包含的 Apache Http Client 似乎具有一些额外的 URL 功能:请参阅org.apache.http.client.utils
See also HTTP URL Address Encoding in Java
回答by McDowell
"http://abc.com:123/abc].mp3"
]
is not allowed in the path part of a URI, so this is not a URL. However, you can modify the regular expression in the specto get this information:
]
不允许出现在 URI 的路径部分,因此这不是 URL。但是,您可以修改规范中的正则表达式以获取此信息:
//TODO: import java.util.regex.*;
String expr = "^(([^:/?#]+):)?(//([^:/?#]*):([\d]*))?";
Matcher matcher = Pattern.compile(expr)
.matcher("http://abc.com:123/abc].mp3");
if (matcher.find()) {
String port = matcher.group(5);
System.out.println(port);
}
Despite the name, URLEncoder
doesn't encode URLs. It should only be used to encode parameters in the query part when the server is expecting application/x-www-form-urlencoded
encoded data. The URI
and URL
classes behave as documented - they aren't going to help you here.
尽管有名称,URLEncoder
但不编码 URL。当服务器需要application/x-www-form-urlencoded
编码数据时,它应该只用于对查询部分中的参数进行编码。在URI
和URL
类表现为记录-他们是不会帮助你在这里。
回答by dave.c
According to RFC1738the ]
character is unsafe:
根据RFC1738的]
字符是不安全的:
Other characters are unsafe because gateways and other transport agents are known to sometimes modify such characters. These characters are "{", "}", "|", "\", "^", "~", "[", "]", and "`".
Thus, only alphanumerics, the special characters "$-_.+!*'(),", and reserved characters used for their reserved purposes may be used unencoded within a URL.
其他字符是不安全的,因为网关和其他传输代理有时会修改这些字符。这些字符是“{”、“}”、“|”、“\”、“^”、“~”、“[”、“]”和“`”。
因此,只有字母数字、特殊字符“$-_.+!*'(),”和用于其保留目的的保留字符可以在 URL 中未编码地使用。
You should encode either the individual character that you want to add, or run the whole string through a URL encoder. Try this:
您应该对要添加的单个字符进行编码,或者通过 URL 编码器运行整个字符串。试试这个:
new URL("http://abc.com:123/abc%5D.mp3").getPort();
回答by user207421
String encodedURL = new URI("http", null, "//abc.com:8080/abc[d].jpg", null, null).toASCIIString();
String encodingURL = new URI("http", null, "//abc.com:8080/abc[d].jpg", null, null).toASCIIString();
回答by Rami Jaamour
Here is a simpler way to extract port from URLs that may be different from HTTP, e.g. JNDI connection URLs:
这是从可能与 HTTP 不同的 URL(例如 JNDI 连接 URL)中提取端口的更简单方法:
int port = 80; // assumption of default port in the URL
Pattern p = Pattern.compile(":\d+"); // look for the first occurrence of colon followed by a number
Matcher matcher = p.matcher(urlSrtr);
if (matcher.find()) {
String portStrWithColon = matcher.group();
if (portStrWithColon.length() > 1) {
String portStr = portStrWithColon.substring(1);
try {
port = Integer.parseInt(portStr);
} catch (NumberFormatException e) {
// handle
}
}
}
return port;