HttpClient 请求一个域名,想知道这个域名的IP地址,以为我们现在一般都是 CDN 负载的,也就是会有多个IP地址,所以有这个需求。
网上找了一下,没有什么好办法。
看了下网上的教材,要从 Socket.getInetAddress().getHostAddress() 获取 IP 地址,看了下源码 HttpConnectionManager 中的成员变量 HttpConnection 的 getSocket() 方法是 protected 的。/**
* Returns the connection socket.
*
* @return the socket.
*
* @since 3.0
*/
protected Socket getSocket() {
return this.socket;
}
所以直接使用不了,我的思路是。
一、获取真实IP、Head信息、请求状态
1. 创建一个 SHttpConnection extends HttpConnection ,根据提示实现需要实现的方法。
再创建一个获取 Socket 的方法。/**
* 从父类获取socket对象
* @return
*/
public Socket getNowSocket() {
return getSocket();
}
2. 创建 SHttpConnectionManager implements HttpConnectionManager ,直接复制 HttpConnectionManager 里的方法,然后修改 HttpConnection 成自己的 SHttpConnection 对象。
3. 开始请求,我的需求只是获取目标的 HTTP 状态,另外还有 IP 地址,以及请求头信息 。/**
* 获取一个连接的状态,IP地址,head信息
* @param url
* @return
*/
public static Map getStatus(String url){
HttpClient client = new HttpClient();
try {
Map 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");
//设置一个 HttpConnectionManager,我们自己实现 HttpConnectionManager
client.setHttpConnectionManager(new SHttpConnectionManager());
//执行
int status = client.executeMethod(method);
//获取 Header
Header[] headers = method.getResponseHeaders();
//头信息转换成Map
Map 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对象
* @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();
}
}
commons-httpclient
commons-httpclient
3.1
如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。
¥我需要走的更远,点击我 赞助。
如果还有疑问,点击我加群,为你提供最好的解答。