URI - getHost возвращает ноль. Зачем?
Почему возвращается первый null
в то время как второй возвращается mail.yahoo.com
?
Разве это не странно? Если нет, какова логика этого поведения?
Подчеркивает ли виновник? Зачем?
public static void main(String[] args) throws Exception {
java.net.URI uri = new java.net.URI("http://broken_arrow.huntingtonhelps.com");
String host = uri.getHost();
System.out.println("Host = [" + host + "].");
uri = new java.net.URI("http://mail.yahoo.com");
host = uri.getHost();
System.out.println("Host = [" + host + "].");
}
4 ответа
Как уже упоминалось в комментариях @hsz, это известная ошибка.
Но давайте отладим и посмотрим на источники URI
учебный класс. Проблема внутри метода:
private int parseHostname(int start, int n)
:
синтаксический анализ первого URI не выполняется в строках if ((p < n) && !at(p, n, ':'))
fail("Illegal character in hostname", p);
это потому что _
символ не предусмотрен внутри блока сканирования, он допускает только буквы, цифры и -
условное обозначение (L_ALPHANUM
, H_ALPHANUM
, L_DASH
а также H_DASH
).
И да, это еще не исправлено в Java 7
,
Это из-за подчеркивания в базовой URI. Просто удалите подчеркивание, чтобы проверить это. Это работает.
Как дано ниже:
public static void main(String[] args) throws Exception {
java.net.URI uri = new java.net.URI("http://brokenarrow.huntingtonhelps.com");
String host = uri.getHost();
System.out.println("Host = [" + host + "].");
uri = new java.net.URI("http://mail.yahoo.com");
host = uri.getHost();
System.out.println("Host = [" + host + "].");
}
Я не думаю, что это ошибка в Java, я думаю, что Java правильно анализирует имена хостов в соответствии со спецификацией, здесь есть хорошие объяснения спецификации: http://en.wikipedia.org/wiki/Hostname и здесь: http://www.netregister.biz/faqit.htm
Конкретно имена хостов НЕ ДОЛЖНЫ содержать подчеркивания.
Рассмотрите возможность использования: new java.net.URL("http://broken_arrow.huntingtonhelps.com").getHost()
вместо. Имеет альтернативную реализацию парсинга. Если у вас есть URI myUri
экземпляр, затем позвоните myUri.toURL().getHost()
,
Я сталкивался с этим URI
проблема в OpenJDK 1.8, и она работала нормально с URL
,
Как уже упоминалось, это известная ошибка JVM. Хотя, если вы хотите сделать HTTP-запрос к такому хосту, вы все равно можете попробовать использовать обходной путь. Основная идея состоит в том, чтобы создать запрос, основываясь на IP, а не на "неправильном" имени хоста. Но в этом случае вам также нужно добавить в запрос заголовок "Host" с правильным (оригинальным) именем хоста.
1. Вырежьте имя хоста из URL (это грубый пример, вы можете использовать более умный способ):
int n = url.indexOf("://");
if (n > 0) { n += 3; } else { n = 0; }
int m = url.indexOf(":", n);
int k = url.indexOf("/", n);
if (-1 == m) { m = k; }
String hostHeader;
if (k > -1) {
hostHeader = url.substring(n, k);
} else {
hostHeader = url.substring(n);
}
String hostname;
if (m > -1) {
hostname = url.substring(n, m);
} else {
hostname = url.substring(n);
}
2: Получить IP-адрес хоста:
String IP = InetAddress.getByName(hostname).getHostAddress();
3: Создайте новый URL на основе IP:
String newURL = url.substring(0, n) + IP + url.substring(m);
4: Теперь используйте HTTP-библиотеку для подготовки запроса на новый URL (псевдокод):
HttpRequest req = ApacheHTTP.get(newUrl);
5: И теперь вы должны добавить заголовок "Host" с правильным (оригинальным) именем хоста:
req.addHeader("Host", hostHeader);
6: Теперь вы можете сделать запрос (псевдокод):
String resp = req.getResponse().asString();