2014-03-31 17 views
2

我確定我缺少一些東西,但是它涉及到我,HttpClient發送請求的行爲與參數不同。HttpClient 4.3更改了參數(查詢)處理?

問題是,帶參數的任何請求都會導致狀態碼爲501. 對於4.2版本,這些請求處理得當。

棘手的部分是,沒有什麼空間有關的爭論和問題也原告時的參數都可以通過URIBuilder建立如下所述: http://hc.apache.org/httpcomponents-client-4.3.x/tutorial/html/fundamentals.html

我想我需要一種方法來把PARAMS: BasicHttpsParams集合,而不是將它們與純粹的uri連接起來 - 因爲它們並不通過HttpGet獲得認可。在這點上,4.2和4.3之間有什麼變化?

這裏是我們的代碼get方法是如何實現的:

private static CloseableHttpClient httpAgent = initializeCloseableHttpClient(connectionManager); 

private static CloseableHttpClient initializeCloseableHttpClient(PoolingHttpClientConnectionManager connectionManager) { 
    RequestConfig requestConfig = RequestConfig.custom() 
           .setConnectTimeout(500) 
           .setConnectionRequestTimeout(DEFAULT_CONNECTION_TIMEOUT) 
           .setSocketTimeout(DEFAULT_SOCKET_TIMEOUT) 
           .build(); 

    ConnectionConfig connectionConfig = ConnectionConfig.custom() 
           .setCharset(StandardCharsets.UTF_8) 
           .build(); 

    CloseableHttpClient httpClient = HttpClients.custom() 
           .setConnectionManager(connectionManager) 
           .setDefaultRequestConfig(requestConfig) 
           .setDefaultConnectionConfig(connectionConfig) 
           .build(); 
    return httpClient; 
} 

public static String get(String url, Map<String, String> arguments) { 
    String argumentString = getArgumentString(arguments == null ? EMPTY_COLLECTION : arguments.entrySet()); 
    HttpGet getMethod = new HttpGet(url + argumentString); 
    return request(getMethod, null); 
} 

private static String request(HttpUriRequest method, AuthenticationDetails authenticationDetails) { 
    InputStreamProcessor processor = new CopyToStringInputStreamProcessor(); 
    processStream(method, authenticationDetails, processor); 
    return (String) processor.getResult(); 
} 

private static void processStream(HttpUriRequest method, AuthenticationDetails authenticationDetails, InputStreamProcessor processor) { 
    try { 
     HttpClientContext context = null; 
     if (authenticationDetails != null) { 

      CredentialsProvider credsProvider = new BasicCredentialsProvider(); 
      UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(authenticationDetails.getUsername(), authenticationDetails.getPassword()); 
      credsProvider.setCredentials(new AuthScope(method.getURI().getHost(), method.getURI().getPort()), credentials); 

      // Create AuthCache instance 
      AuthCache authCache = new BasicAuthCache(); 
      // Generate BASIC scheme object and add it to the local auth cache 
      BasicScheme basicAuth = new BasicScheme(); 
      HttpHost targetHost = new HttpHost(method.getURI().getHost(), method.getURI().getPort(), method.getURI().getScheme()); 
      authCache.put(targetHost, basicAuth); 

      // Add AuthCache to the execution context 
      context = HttpClientContext.create(); 
      context.setCredentialsProvider(credsProvider); 
      context.setAuthCache(authCache); 
     } 

     for (int i = 0; i < 3; i++) { 
      CloseableHttpResponse response = httpAgent.execute(method, context); 

      int statusCode = response.getStatusLine().getStatusCode(); 
      if (statusCode != 200 && statusCode != 302) { // redirect is also ok 
       throw new HttpClientException(String.format("A http request responds with failure code: %d (%s), requested uri: %s", statusCode, response.getStatusLine().getReasonPhrase(), method.getRequestLine().getUri())); 
      } 

      try { 
       HttpEntity entity = response.getEntity(); 
       if (entity != null) { 
        try (InputStream responseStream = entity.getContent()) { 
         processor.process(responseStream); 
         EntityUtils.consume(entity); 
        } 
        catch (IOException ex) { 
         throw ex; // In case of an IOException the connection will be released back to the connection manager automatically 
        } 
        catch (RuntimeException ex) { 
         method.abort(); // In case of an unexpected exception you may want to abort the HTTP request in order to shut down the underlying connection and release it back to the connection manager. 
         throw ex; 
        } 
       } 
      } finally { 
       response.close(); 
      } 
     } 
    } 
    catch (IOException e) { 
     throw new HttpClientException(String.format("IO exception while processing http request on url: %s. Message: %s", method.getRequestLine().getUri(), e.getMessage()), e); 
    } 
    catch (Exception e) { 
     throw new HttpClientException(String.format("Exception while processing http request on on url: %s. Message: %s", method.getRequestLine().getUri(), e.getMessage()), e); 
    } 
} 

任何建議什麼可能是錯誤的高度讚賞。

謝謝

+0

打印您的請求和回覆標題,可能會有用。 – vzamanillo

+0

在兩種情況下(遷移前後)標頭組都是空的 – Macilias

+0

上述內容對於請求有效。響應標頭如下所示:HttpClient 2.5:[Date:Mon,31 Mar 2014 13:08:40 GMT,Server:LocalTestServer/1.1,Content-Length:8,Content-Type:text/plain; charset = UTF-8,Connection:Keep-Alive] HttpClient 3.3:[Date:Mon,31 Mar 2014 13:12:43 GMT,Content-Length:0,Connection:Close] – Macilias

回答

0

5xx是服務器錯誤。在查看服務器日誌之前,沒有理由認爲客戶端上有任何問題。如果您無法訪問服務器日誌,請檢查響應文本,可能會指出服務器中發生了什麼故障。

+0

我會照你想的那樣做,但奇怪的是相同的(測試服務器)實例在HttpClient 4.2中完成了她的工作 – Macilias

+0

很可能在4.3.x中發生了一些變化,導致服務器失敗。但要找出從服務器開始診斷的最佳方法。 –

+0

這兩個會話(4.2和4.3)的連線日誌也可能有助於http://hc.apache.org/httpcomponents-client-4.3.x/logging.html – oleg

0

這個問題在下面的循環鋪設:

for (int i = 0; i < 3; i++) {...} 

我不知道什麼時候發現到的代碼,雖然它有它的原因,請求IST sendet 3倍,但發現除去這個之前和之後沒有,所有東西都開始正常工作。