【发布时间】:2014-05-10 14:35:54
【问题描述】:
我确定我遗漏了一些东西,但在我看来,HttpClient 发送请求的行为在参数方面有所不同。
问题是,任何带有参数的请求都会导致状态码 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);
}
}
非常感谢任何可能出错的建议。
谢谢
【问题讨论】:
-
打印您的请求和响应标头,可能会有用。
-
头组在两种情况下都是空的(迁移前后)
-
以上对请求有效。响应标头如下所示:HttpClient 2.5:[日期:星期一,2014 年 3 月 31 日 13:08:40 GMT,服务器:LocalTestServer/1.1,内容长度:8,内容类型:文本/纯文本; charset=UTF-8, Connection: Keep-Alive] HttpClient 3.3: [日期: Mon, 31 Mar 2014 13:12:43 GMT, Content-Length: 0, Connection: Close]
标签: java httpclient apache-httpclient-4.x