出于测试目的,我正在尝试将套接字工厂添加到我的okHttp客户端,该客户端在设置代理时信任所有内容.这已经完成了很多次,但是我对一个信任套接字工厂的实现似乎缺少了一些东西:
class TrustEveryoneManager implements X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
OkHttpClient client = new OkHttpClient();
final InetAddress ipAddress = InetAddress.getByName("XX.XXX.XXX.XXX"); // some IP
client.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, 8888)));
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = new TrustManager[]{new TrustEveryoneManager()};
sslContext.init(null, trustManagers, null);
client.setSslSocketFactory(sslContext.getSocketFactory);
Run Code Online (Sandbox Code Playgroud)
没有请求从我的应用程序发出,并且没有异常被记录,因此它似乎在okHttp中无声地失败.经过进一步调查,似乎Connection.upgradeToTls()在强制握手时,okHttp中有一个异常被吞没.我得到的例外是:javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You …
这是我如何使用它 -
private static final PoolingHttpClientConnectionManager connPool;
static {
connPool = new PoolingHttpClientConnectionManager();
// Increase max total connection to 200
connPool.setMaxTotal(200);//configurable through app.properties
// Increase default max connection per route to 50
connPool.setDefaultMaxPerRoute(20);//configurable through app.properties
}
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connPool) .build();
Run Code Online (Sandbox Code Playgroud)
另外我在http GET周围放了一个finally块 -
finally {
try {
httpClient.close();
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的堆栈跟踪 -
java.lang.IllegalStateException: Connection pool shut down
at org.apache.http.util.Asserts.check(Asserts.java:34)
at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:169)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:217)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:157)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at …Run Code Online (Sandbox Code Playgroud) 我继承了代码
import org.apache.http.client.HttpClient;
...
HttpClient httpclient = createHttpClientOrProxy();
...
private HttpClient createHttpClientOrProxy() {
HttpClient httpclient = new DefaultHttpClient();
/*
* Set an HTTP proxy if it is specified in system properties.
*
* http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
* http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientExecuteProxy.java
*/
if( isSet(System.getProperty("http.proxyHost")) ) {
int port = 80;
if( isSet(System.getProperty("http.proxyPort")) ) {
port = Integer.parseInt(System.getProperty("http.proxyPort"));
}
HttpHost proxy = new HttpHost(System.getProperty("http.proxyHost"), port, "http");
// @Deprecated methods here... getParams() and ConnRoutePNames
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
return httpclient;
}
Run Code Online (Sandbox Code Playgroud)
httpClient.getParams() 是@Deprecated并读"
HttpParams getParams()
Deprecated.
(4.3) use …Run Code Online (Sandbox Code Playgroud) 处理特定网站时,有时我会收到状态码为403的http响应.我想在这种情况下重新执行请求(因为,在我的特定情况下,此服务器在实际超载时会抛出403).我试图和a ResponseHandler一起使用StandardHttpRequestRetryHandler,但它没有按照我希望的方式工作; 我期望在ResponseHandler触发器中抛出异常会触发StandardHttpRequestRetryHandler,但似乎并非如此.如何实现所需的功能?
这是一个示例代码,说明了我的情况:
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
public class Main {
public static void main(String[] args) throws Exception {
// a response handler that throws an exception if status is not 200
ResponseHandler<String> responseHandler = new ResponseHandler<String> () {
@Override
public String handleResponse(HttpResponse response) throws
ClientProtocolException, IOException
{
System.out.println("-> Handling response");
if (response.getStatusLine().getStatusCode() != …Run Code Online (Sandbox Code Playgroud) 有没有人在Android 4.4上使用Apache HttpClient 4.3?无论我在eclipse中导出apache jar的顺序是什么,设备使用Android SDK附带的Apache HttpClient版本.
在nGinx服务器端,为客户端设置connection-keep alive最多30秒.但是使用这个代码和附加的日志,HttpClient 4.3.并不尊重保持活力并在每次请求后关闭连接.为什么会这样?
我在重复尝试netstat -an并发现客户端在for循环执行期间的不同时间打开不同的端口并且FIN状态每2秒进行一次时得出了这个结论.
下面给出的日志还显示每次请求后关闭连接
static ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
return 30 * 1000;
}
};
public static void main(String[] args) throws Exception {
java.util.logging.Logger.getLogger("org.apache.http.wire").setLevel(java.util.logging.Level.FINER);
java.util.logging.Logger.getLogger("org.apache.http.headers").setLevel(java.util.logging.Level.FINER);
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers", "debug");
callServer();
}
public static void callServer() throws Exception {
KeyStore keyStore = KeyStore.getInstance("pkcs12");
FileInputStream instream = new FileInputStream(new File("/engineering/workspace/nginx_pilot/keystores/clientkeystore.pkcs"));
try {
keyStore.load(instream, "****".toCharArray());
} finally {
instream.close();
}
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
instream = …Run Code Online (Sandbox Code Playgroud) 在 Apache HttpClient 4.2 中,可以创建一个DefaultHttpClient并设置一个主机,这样进行execute调用的人就不必在输入请求 URI 中提供主机信息,即:
HttpHost targetHost = new HttpHost(host, port, secure ? "https" : "http");
DefaultHttpClient defaultHttp = new DefaultHttpClient(connectionManager);
defaultHttp.getParams().setParameter(ClientPNames.DEFAULT_HOST, targetHost);
Run Code Online (Sandbox Code Playgroud)
我承认这个策略看起来很尴尬,我继承了这段代码:)。我确信在 4.2 中有更好的方法来做到这一点。
我希望升级到 4.3 并注意到DefaultHttpClient和ClientPNames现在分别被弃用HttpClientBuilder和RequestConfig。但是我找不到这样的方法来定义默认目标RequestConfig。
执行文档确实提到该输入目标参数可以接受空值,所以我确信仍然有一种方法可以促进这一点,但我正在努力弄清楚这一点:
target - 请求的目标主机。如果实现仍然可以确定路由,例如到默认目标或通过检查请求,则它们可以接受 null。
我正在尝试在我的应用程序中使用 HTTPAsyncCLient 进行即发即忘。
http://hc.apache.org/httpcomponents-asyncclient-4.0.x/
但对于真正的即发即忘,我需要避免关闭客户端,因为我不想等待响应,如果我关闭,则可能直到那时才建立连接。
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
httpclient.start();
HttpGet request = new HttpGet(url);
Future<HttpResponse> future = httpclient.execute(request, null);
HttpResponse resp = future.get();
httpclient.close();
Run Code Online (Sandbox Code Playgroud)
所以一个想法是我不关闭 httpclient,并继续将它用于多个 URL。因此,我将在服务器启动时生成一个客户端,并继续对所有请求使用相同的客户端。
这样,就不需要关闭,因为只有当服务器停止时才会释放它。我的问题是这会成为问题吗?一段时间后客户端会变得陈旧吗?