我正在尝试通过java访问Web API。
API位于https服务器上。
不幸的是它工作得很慢。
当我通过网络浏览器访问API时, 它在1秒内给出响应。
当我通过java访问API时, 它会在3秒内给出响应。
我做错了什么?如何更快地获得响应?
我注意到缓慢的部分是这一行: HttpResponse response1 = httpclient.execute(httpGet);
这是我的代码:
static DefaultHttpClient httpclient ;
static {
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("LOGIN", "PASSWORD");
httpclient = new DefaultHttpClient();
HttpHost targetHost = new HttpHost("SERVER.org", 443, "https");
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
creds);
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local
// auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
readXml("https://SERVER.org/PATH");
}
public static String readXml(String urlToRead){
try {
HttpGet httpGet = new HttpGet(urlToRead);
HttpResponse response1 = httpclient.execute(httpGet);
try {
System.out.println(response1.getStatusLine());
HttpEntity entity1 = response1.getEntity();
BufferedReader in;
String inputLine;
String result="";
try {
in = new BufferedReader(new InputStreamReader(entity1.getContent(),"UTF-8"));
while ((inputLine = in.readLine()) != null) {
result+=inputLine+"\n";
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
} finally {
httpGet.releaseConnection();
}
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
返回null; }
答案 0 :(得分:1)
我认为HTTPS握手速度很慢。每个请求中没有新的DefaultHttpClient的原因。您应该使用PoolingClientConnectionManager来处理多个http-client。
public Client(int maxConnectPerHost, int maxConnection, int connectTimeOut, int socketTimeOut,
String cookiePolicy, boolean isAutoRetry, boolean redirect) {
SSLContext sslcontext = null;
try {
sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(null, new TrustManager[] {
new TrustAnyTrustManager()
}, new java.security.SecureRandom());
} catch (Exception e) {
// throw something
}
// if a ssl certification is not correct, it will not throw any exceptions.
Scheme https = new Scheme("https", 443, new SSLSocketFactory(sslcontext,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER));
Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
SchemeRegistry sr = new SchemeRegistry();
sr.register(https);
sr.register(http);
connectionManager = new PoolingClientConnectionManager(sr, socketTimeOut, TimeUnit.SECONDS);
connectionManager.setDefaultMaxPerRoute(maxConnectPerHost);
connectionManager.setMaxTotal(maxConnection);
HttpParams params = new BasicHttpParams();
params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, connectTimeOut);
params.setParameter(ClientPNames.COOKIE_POLICY, cookiePolicy);
params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, redirect);
params.setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, false);
if (isAutoRetry) {
client = new AutoRetryHttpClient(new DefaultHttpClient(connectionManager, params));
} else {
client = new DefaultHttpClient(connectionManager, params);
}
}
然后使用客户端发送请求。客户应该是单身人士。这是doGet方法。并且不应该释放连接。
public HttpResponse doGet(String url, List<Header> headers)
throws Exception {
HttpGet get = new HttpGet(url);
if (headers != null) {
Header[] array = new Header[headers.size()];
headers.toArray(array);
get.setHeaders(array);
}
try {
HttpResponse resp = client.execute(get);
return resp;
} catch (Exception e) {
// throw something
}
}
以下是请求:
Client c = new Client(1024, 1024 * 1024, 10000, 10000, CookiePolicy.IGNORE_COOKIES, true, true);
HttpResponse r = null;
try {
r = c.doGet("your url", null);
} finally{
if (r != null) {
EntityUtils.consumeQuietly(r.getEntity());
}
}
// send request again. There is no https handshake in this time.
try {
r = c.doGet("your url", null);
} finally{
if (r != null) {
EntityUtils.consumeQuietly(r.getEntity());
}
}
握手会降低您的申请速度。因此,您不应在每个请求中关闭/释放连接。