2016-07-06 55 views
4

我有以下方法使用代理從服務器檢索信息。有時由於錯誤的代理,我得到SocketExceptionSSLExceptionSSLHandshakeExceptionConnectException重試對某些例外的方法

正如你在我已經使用catch (IOException ioe)我的方法看,我需要做的是,爲了獲得服務器響應的內容,如果服務器返回什麼而不是代碼200.

如何在上述例外的情況下使方法重試?

public String getMeta() throws IOException 
{ 

    HttpsURLConnection con = null; 
    InputStream is = null; 
    StringWriter writer = new StringWriter(); 
    try 
    { 
     String url = "https://api.myapp.com/meta"; 
     URL urlObj = new URL(url); 

     if (useProxy && fullProxy) 
     { 
      myapp.Proxy proxyCustom = getRandomProxy(); 
      Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyCustom.getProxyIp(), proxyCustom.getProxyPort())); 
      con = (HttpsURLConnection) urlObj.openConnection(proxy); 
     } 
     else 
     { 
      con = (HttpsURLConnection) urlObj.openConnection(); 
     } 

     con.setRequestMethod("GET"); 
     con.setRequestProperty("User-Agent", USER_AGENT); 
     con.setRequestProperty("Content-Type", "application/json; charset=utf-8"); 
     con.setRequestProperty("host", urlObj.getHost()); 
     con.setRequestProperty("Connection", "Keep-Alive"); 

     int responseCode = 0; 

     responseCode = con.getResponseCode(); 

     is = con.getInputStream(); 
     writer = new StringWriter(); 
     IOUtils.copy(is, writer, "UTF-8"); 
    } 
    catch (IOException ioe) 
    { 
     if (con instanceof HttpsURLConnection) 
     { 
      HttpsURLConnection httpConn = (HttpsURLConnection) con; 
      int statusCode = httpConn.getResponseCode(); 
      if (statusCode != 200) 
      { 
       is = httpConn.getErrorStream(); 
       writer = new StringWriter(); 
       IOUtils.copy(is, writer, "UTF-8"); 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

    return writer.toString(); 
} 
+0

使用循環或遞歸。如果你想避免那些東西和無盡的遞歸/循環,沒有額外的邏輯,只需將try-block中的所有內容都放到一個新的方法中即可。然後你可以再打一次電話。 – HopefullyHelpful

+1

'我如何使方法重試'您想重試一次,還是不斷重試,直到沒有異常拋出? – copeg

+0

@copeg我希望有一個簡單的方法來設置它應該重試的時間,但它太複雜了,我只會嘗試一次。 – Arya

回答

0

我會做的方式是創建一個新的重試方法,並在您的getMeta()方法的最後調用它,所以它被稱爲只有在異常情況下 我假設你應該只調用重試幾次,因此getMeta應該一定次數

public String getMeta() throws IOException, RetryException 
{ 

    HttpsURLConnection con = null; 
    InputStream is = null; 
    StringWriter writer = new StringWriter(); 
    try 
    { 
     String url = "https://api.myapp.com/meta"; 
     URL urlObj = new URL(url); 

     if (useProxy && fullProxy) 
     { 
      myapp.Proxy proxyCustom = getRandomProxy(); 
      Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyCustom.getProxyIp(), proxyCustom.getProxyPort())); 
      con = (HttpsURLConnection) urlObj.openConnection(proxy); 
     } 
     else 
     { 
      con = (HttpsURLConnection) urlObj.openConnection(); 
     } 

     con.setRequestMethod("GET"); 
     con.setRequestProperty("User-Agent", USER_AGENT); 
     con.setRequestProperty("Content-Type", "application/json; charset=utf-8"); 
     con.setRequestProperty("host", urlObj.getHost()); 
     con.setRequestProperty("Connection", "Keep-Alive"); 

     int responseCode = 0; 

     responseCode = con.getResponseCode(); 

     is = con.getInputStream(); 
     writer = new StringWriter(); 
     IOUtils.copy(is, writer, "UTF-8"); 

     return writer.toString(); 
    } 
    catch (IOException ioe) 
    { 
     if (con instanceof HttpsURLConnection) 
     { 
      HttpsURLConnection httpConn = (HttpsURLConnection) con; 
      int statusCode = httpConn.getResponseCode(); 
      if (statusCode != 200) 
      { 
       is = httpConn.getErrorStream(); 
       writer = new StringWriter(); 
       IOUtils.copy(is, writer, "UTF-8"); 

       return writer.toString(); 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

    return retryGetMeta(); 
} 


private String retryGetMeta() 
{ 
    try 
    { 
     return getMeta(); 
    } 
    finally 
    { 
     //Do your stuff 
    } 
} 

public RetryException extends Exception 
{ 
    private String message = "Retries exceeded"; 

     public String getMessage() 
     { 
     return message; 
     } 

} 

如果異常在getMeta(),捉將盡自己的東西,你現在所做的拋出後拋出一些例外,像RetryException,但在那之後, retryGetMeta將被稱爲

+0

感謝您的回答,所以這不會在IOException的情況下被調用嗎?但是當拋出SocketException,SSLException,SSLHandshakeException或ConnectException時會調用它? – Arya

+0

是的,如果你想返回writer.toString()包含IOException,那麼重試將不會被調用。在IOException異常情況下修改代碼以返回writer,所有其他異常將調用重試 – SomeDude

0

如何在上述例外的情況下使方法重試?

下面的一種方法是讓getMeta方法實際上拋出IOException。然後,您可以通過遞歸調用caller方法來捕獲異常。

我希望有設置一個簡單的方法應該如何次重試

爲了能夠調用的次數方法n數,次數作爲參數傳遞和處理相應的停止標準邏輯。例如:

public String caller(int total) throws IOException{ 
    return callerImpl(1, total); 
} 

public String callerImpl(int current, int total) throws IOException{ 
    try{ 
     return getMeta(); 
    }catch(IOException e){ 
     current++; 
     if (current > total){ 
      throw e;//or return null or empty string, depending upon upstream requirements 
     } 
     return callerImpl(current, total); 
    } 

    return null; 
} 

在getMeta:

try{ 
    .... 
}catch(IOException io){ 
    //log or handle io 
    throw io; 
} 

注意上面沒有處理拋出的異常,這可能需要以某種方式來處理的日誌/邏輯。

相關問題