Java処理HTTP要求のタイムアウトの問題を解決します。
POSTまたはGET要求を送信した場合、タイムアウト異常処理方法を返します。
SocketTimeout Exception|Connect Timeout Exception|Connection Pool Timeoutを捕獲すると異常です。
三つの異常説明:
HTTPserverを接続するか、HttpConnection Manager管理の有効な接続を待つか、タイムアウトエラーが発生したらConnection Timeout Exceptionをスローします。
まとめ:
SocketTimeout Exception異常は汎用的な異常であり、元のHTTP要求を使っても、Apacheの下のHttpClientパッケージを使っても、投げられた異常の中でSocketTimeout Exception異常を捕獲する必要があります。
例:
業務の背景:
あるプロジェクトは第三者会社とドッキングします。
業務説明:
データの安全性を考慮して、サーバーから要求を送信する必要があります。第三者会社が提供するインターフェースを呼び出します。ただし、このシーンは販売タイプで、応答時間が十分速いと、応答のタイムアウト処理を設定します。
さもなくば取引先に丸を見ていさせてそこで半日回転して、誰が買いますか?
プロジェクトアーキテクチャ:
jdk 1.7
スプリング4.2.9
詳細:
SocketTimeout Exception|Connect Timeout Exception|Connection Pool Timeoutを捕獲すると異常です。
三つの異常説明:
SocketTimeoutException
:Javaパケットの下で投げられた異常であり、これは、Socket読み取りデータのタイムアウト時間、すなわちserverから応答データを取得するのに待つ時間を定義している。Socketのタイムアウトを読み込みまたは受信すると、SocketTimeout Exceptionが投げ出されます。ConnectTimeoutException
:ApacheのHttpClientパッケージから投げられたタイムアウト異常で、ネットワークを通じてserverと接続を確立するタイムアウト時間を定義しています。Httpclientパッケージの中で、非同期スレッドを通してserverのsocketと接続を作成します。HTTPserverを接続するか、HttpConnection Manager管理の有効な接続を待つか、タイムアウトエラーが発生したらConnection Timeout Exceptionをスローします。
ConnectionPoolTimeout
:AppleのHttpClientパッケージからのタイムアウト異常であり、Connection Managerが管理する接続池から接続を取り出すタイムアウト時間を定義しています。エラーはConnection Pool Timeout Exceptionを投げます。まとめ:
SocketTimeout Exception異常は汎用的な異常であり、元のHTTP要求を使っても、Apacheの下のHttpClientパッケージを使っても、投げられた異常の中でSocketTimeout Exception異常を捕獲する必要があります。
例:
public static String doGet(String url, Object params, String contentType) {
try {
return HttpUtils.doGetSend(url, params, contentType);
} catch (SocketTimeoutException | ConnectTimeoutException e) {
e.printStackTrace();
System.out.println(" :" + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
System.out.println(" , :" + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
補足:javaがhttp要求を送信する(接続タイムアウト処理)業務の背景:
あるプロジェクトは第三者会社とドッキングします。
業務説明:
データの安全性を考慮して、サーバーから要求を送信する必要があります。第三者会社が提供するインターフェースを呼び出します。ただし、このシーンは販売タイプで、応答時間が十分速いと、応答のタイムアウト処理を設定します。
さもなくば取引先に丸を見ていさせてそこで半日回転して、誰が買いますか?
プロジェクトアーキテクチャ:
jdk 1.7
スプリング4.2.9
詳細:
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httpPost = new HttpPost( URL);
//
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000).setConnectionRequestTimeout(5000)
.setSocketTimeout(5000).build();
httpPost.setConfig(requestConfig);
// post
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("attr1", 1));
nvps.add(new BasicNameValuePair("attr2", 2));
nvps.add(new BasicNameValuePair("attr3", 3));
……
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
// post
CloseableHttpResponse response = httpclient.execute(httpPost);
// (0--200 )
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//
responseMessage = EntityUtils.toString(response.getEntity(),"utf-8");
System.out.println(responseMessage);
if(responseMessage!=null && !"".equals(responseMessage)){
String data = new String(AESUtil.decrypt(Base64.decode(responseMessage), key),"UTF-8");
String msg = translate_PRE(data,trans_type,transNo);
result.put("msg", msg);
}
}else{
System.out.println(" : "+ response.getStatusLine());
}
} catch (ConnectTimeoutException e) {
System.out.println(api_type+" ");
} catch (ClientProtocolException e) {
System.out.println(" ");
} catch (Exception e) {
e.printStackTrace();
} finally {
//
try {
if(httpclient!=null){
httpclient.close();
}
} catch (IOException e) {
System.out.println(api_type+" ");
}
}
.setConnectTimeout(5000).setConnectionRequestTimeout(5000)
.setSocketTimeout(5000).build();
httpPost.setConfig(requestConfig);
// post
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("attr1", 1));
nvps.add(new BasicNameValuePair("attr2", 2));
nvps.add(new BasicNameValuePair("attr3", 3));
……
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
// post
CloseableHttpResponse response = httpclient.execute(httpPost);
// (0--200 )
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//
responseMessage = EntityUtils.toString(response.getEntity(),"utf-8");
System.out.println(responseMessage);
if(responseMessage!=null && !"".equals(responseMessage)){
String data = new String(AESUtil.decrypt(Base64.decode(responseMessage), key),"UTF-8");
String msg = translate_PRE(data,trans_type,transNo);
result.put("msg", msg);
}
}else{
System.out.println(" : "+ response.getStatusLine());
}
} catch (ConnectTimeoutException e) {
System.out.println(api_type+" ");
} catch (ClientProtocolException e) {
System.out.println(" ");
} catch (Exception e) {
e.printStackTrace();
} finally {
//
try {
if(httpclient!=null){
httpclient.close();
}
} catch (IOException e) {
System.out.println(api_type+" ");
}
}
以上は個人の経験ですので、参考にしていただければと思います。間違いがあったり、完全に考えていないところがあれば、教えてください。