HttpClient獲取訪問域名的真實(shí)ip,HttpClient請(qǐng)求獲取目標(biāo)IP地址
HttpClient 請(qǐng)求一個(gè)域名,想知道這個(gè)域名的IP地址,以為我們現(xiàn)在一般都是 CDN 負(fù)載的,也就是會(huì)有多個(gè)IP地址,所以有這個(gè)需求。
網(wǎng)上找了一下,沒有什么好辦法。
看了下網(wǎng)上的教材,要從 Socket.getInetAddress().getHostAddress() 獲取 IP 地址,看了下源碼 HttpConnectionManager 中的成員變量 HttpConnection 的 getSocket() 方法是 protected 的。
/**
* Returns the connection socket.
*
* @return the socket.
*
* @since 3.0
*/
protected Socket getSocket() {
return this.socket;
}所以直接使用不了,我的思路是。
一、獲取真實(shí)IP、Head信息、請(qǐng)求狀態(tài)
1. 創(chuàng)建一個(gè) SHttpConnection extends HttpConnection ,根據(jù)提示實(shí)現(xiàn)需要實(shí)現(xiàn)的方法。
再創(chuàng)建一個(gè)獲取 Socket 的方法。
/**
* 從父類獲取socket對(duì)象
* @return
*/
public Socket getNowSocket() {
return getSocket();
}2. 創(chuàng)建 SHttpConnectionManager implements HttpConnectionManager ,直接復(fù)制 HttpConnectionManager 里的方法,然后修改 HttpConnection 成自己的 SHttpConnection 對(duì)象。
3. 開始請(qǐng)求,我的需求只是獲取目標(biāo)的 HTTP 狀態(tài),另外還有 IP 地址,以及請(qǐng)求頭信息 。
/**
* 獲取一個(gè)連接的狀態(tài),IP地址,head信息
* @param url
* @return
*/
public static Map<String,Object> getStatus(String url){
HttpClient client = new HttpClient();
try {
Map<String,Object> result = new TreeMap<>();
client.getHttpConnectionManager().getParams().setConnectionTimeout(1500);
client.getHttpConnectionManager().getParams().setSoTimeout(1500);
//瀏覽器方式模擬
client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"UTF-8");
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
GetMethod method = new GetMethod(url);
//必要的頭信息
method.setRequestHeader("Accept", "*/*");
method.setRequestHeader("Accept-Encoding", "gzip, deflate");
method.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
method.setRequestHeader("Connection","close");
method.setRequestHeader("Host", url);
method.setRequestHeader("Referer", "https://www.baidu.com/s?wd=sojson");
method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0");
//設(shè)置一個(gè) HttpConnectionManager,我們自己實(shí)現(xiàn) HttpConnectionManager
client.setHttpConnectionManager(new SHttpConnectionManager());
//執(zhí)行
int status = client.executeMethod(method);
//獲取 Header
Header[] headers = method.getResponseHeaders();
//頭信息轉(zhuǎn)換成Map
Map<String,Object> map = Arrays.stream(headers).collect(Collectors.toMap(Header::getName,Header::getValue));
//獲取 HttpConnectionManager
SHttpConnectionManager manager = (SHttpConnectionManager)client.getHttpConnectionManager();
Socket hostAddress = manager.getNowSocket();
String ip = hostAddress.getInetAddress().getHostAddress();
result.put("ip",ip);
result.put("status",status);
result.put("header",map);
return result;
} catch (IOException e) {
return null;
}
}二、SHttpConnection 和 SHttpConnectionManager 的源碼
1.SHttpConnection 源碼
public class SHttpConnection extends HttpConnection{
public SHttpConnection(String host, int port) {
super(host, port);
}
/**
* 從父類獲取socket對(duì)象
* @return
*/
public Socket getNowSocket() {
return getSocket();
}
public SHttpConnection(String host, int port, Protocol protocol) {
super(host, port, protocol);
}
public SHttpConnection(String host, String virtualHost, int port, Protocol protocol) {
super(host, virtualHost, port, protocol);
}
public SHttpConnection(String proxyHost, int proxyPort, String host, int port) {
super(proxyHost, proxyPort, host, port);
}
public SHttpConnection(HostConfiguration hostConfiguration) {
super(hostConfiguration);
}
public SHttpConnection(String proxyHost, int proxyPort, String host, String virtualHost, int port, Protocol protocol) {
super(proxyHost, proxyPort, host, virtualHost, port, protocol);
}
public SHttpConnection(String proxyHost, int proxyPort, String host, int port, Protocol protocol) {
super(proxyHost, proxyPort, host, port, protocol);
}
}2.SHttpConnectionManager 源碼
public class SHttpConnectionManager implements HttpConnectionManager {
private static final Log LOG = LogFactory.getLog(SimpleHttpConnectionManager.class);
private static final String MISUSE_MESSAGE = "SimpleHttpConnectionManager being used incorrectly. Be sure that"
+ " HttpMethod.releaseConnection() is always called and that only one thread"
+ " and/or method is using this connection manager at a time.";
static void finishLastResponse(HttpConnection conn) {
InputStream lastResponse = conn.getLastResponseInputStream();
if (lastResponse != null) {
conn.setLastResponseInputStream(null);
try {
lastResponse.close();
} catch (IOException ioe) {
conn.close();
}
}
}
protected SHttpConnection httpConnection;
private HttpConnectionManagerParams params = new HttpConnectionManagerParams();
private long idleStartTime = Long.MAX_VALUE;
private volatile boolean inUse = false;
private boolean alwaysClose = false;
public SHttpConnectionManager() {
super();
}
public HttpConnection getConnection(HostConfiguration hostConfiguration) {
return getConnection(hostConfiguration, 0);
}
public Socket getNowSocket() {
return this.httpConnection.getNowSocket();
}
public boolean isConnectionStaleCheckingEnabled() {
return this.params.isStaleCheckingEnabled();
}
public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) {
this.params.setStaleCheckingEnabled(connectionStaleCheckingEnabled);
}
public HttpConnection getConnectionWithTimeout(
HostConfiguration hostConfiguration, long timeout) {
if (httpConnection == null) {
httpConnection = new SHttpConnection(hostConfiguration);
httpConnection.setHttpConnectionManager(this);
httpConnection.getParams().setDefaults(this.params);
} else {
if (!hostConfiguration.hostEquals(httpConnection)
|| !hostConfiguration.proxyEquals(httpConnection)) {
if (httpConnection.isOpen()) {
httpConnection.close();
}
httpConnection.setHost(hostConfiguration.getHost());
httpConnection.setPort(hostConfiguration.getPort());
httpConnection.setProtocol(hostConfiguration.getProtocol());
httpConnection.setLocalAddress(hostConfiguration.getLocalAddress());
httpConnection.setProxyHost(hostConfiguration.getProxyHost());
httpConnection.setProxyPort(hostConfiguration.getProxyPort());
} else {
finishLastResponse(httpConnection);
}
}
// remove the connection from the timeout handler
idleStartTime = Long.MAX_VALUE;
if (inUse) LOG.warn(MISUSE_MESSAGE);
inUse = true;
return httpConnection;
}
public HttpConnection getConnection(
HostConfiguration hostConfiguration, long timeout) {
return getConnectionWithTimeout(hostConfiguration, timeout);
}
public void releaseConnection(HttpConnection conn) {
if (conn != httpConnection) {
throw new IllegalStateException("Unexpected release of an unknown connection.");
}
if (this.alwaysClose) {
httpConnection.close();
} else {
finishLastResponse(httpConnection);
}
inUse = false;
idleStartTime = System.currentTimeMillis();
}
public HttpConnectionManagerParams getParams() {
return this.params;
}
public void setParams(final HttpConnectionManagerParams params) {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
this.params = params;
}
public void closeIdleConnections(long idleTimeout) {
long maxIdleTime = System.currentTimeMillis() - idleTimeout;
if (idleStartTime <= maxIdleTime) {
httpConnection.close();
}
}
public void shutdown() {
httpConnection.close();
}
}3. Maven 依賴
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>版權(quán)所屬:SO JSON在線解析
原文地址:http://suancuo.cn/blog/319.html
轉(zhuǎn)載時(shí)必須以鏈接形式注明原始出處及本聲明。
如果本文對(duì)你有幫助,那么請(qǐng)你贊助我,讓我更有激情的寫下去,幫助更多的人。
