簡體   English   中英

URI - getHost返回null。為什么?

[英]URI - getHost returns null. Why?

為什么第一個返回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 + "].");
}

正如@hsz的評論中提到的那樣,它已知錯誤

但是,讓我們調試並查看URI類的內部源代碼。 問題出在方法內:

private int parseHostname(int start, int n)

if ((p < n) && !at(p, n, ':')) fail("Illegal character in hostname", p);解析第一個URI在行if ((p < n) && !at(p, n, ':')) fail("Illegal character in hostname", p);

這是因為在掃描塊內沒有預見_符號,它只允許使用alphas,digits和- symbol( L_ALPHANUMH_ALPHANUML_DASHH_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#Restrictions_on_valid_host_names ,這里: http://www.netregister.biz/faqit.htm#1

特別是主機名不得包含下划線。

如前所述,這是一個已知的JVM錯誤。 雖然,如果要對此類主機執行HTTP請求,您仍可以嘗試使用變通方法。 主要思想是構建基於IP的請求,而不是基於“錯誤”的主機名。 但在這種情況下,您還需要使用正確的(原始)主機名向請求添加“主機”標頭。

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:根據IP構建新的URL:

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();

考慮使用: new java.net.URL("http://broken_arrow.huntingtonhelps.com").getHost()代替。 它具有替代解析實現。 如果你有一個URI myUri實例,那么調用myUri.toURL().getHost()

我在OpenJDK 1.8中遇到了這個URI問題,它在URL運行良好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM