Java Httpcomponents httpcore和httpclient HTTP_状态400
我正在努力做到:Java Httpcomponents httpcore和httpclient HTTP_状态400,java,apache-httpclient-4.x,apache-httpcomponents,http-status-code-400,http-status-code-200,Java,Apache Httpclient 4.x,Apache Httpcomponents,Http Status Code 400,Http Status Code 200,我正在努力做到: 从HttpClient发送请求(基于HttpComponents HttpClient 4.5) 在HttpServer中接收该请求(基于HttpComponents HttpCore 4.4.1) HttpServer必须以不同的HttpStatus代码和字符串实体作为主体响应HttpClient 问题:若HttpServer使用状态代码200(或任何其他状态代码,未选中)进行应答,那个么它工作正常,服务器端并没有异常。但若服务器设置了应答状态代码400,那个么HttpSer
HttpProcessor httpproc = HttpProcessorBuilder.create()
.add(new ResponseDate())
.add(new ResponseServer("HTTP/1.1 WTX Server"))
.add(new ResponseContent())
.add(new ResponseConnControl()).build();
UriHttpAsyncRequestHandlerMapper reqistry = new UriHttpAsyncRequestHandlerMapper();
reqistry.register("*", new HttpServerURLHandler());
HttpAsyncService protocolHandler = new HttpServerConnectionsHandler(httpproc, reqistry);
try {
String keyStoreFile = Config.getString("HTTPServer.keyStoreFile");
String keyStoreFilePassword = Config.getString("HTTPServer.keyStoreFilePassword");
FileInputStream fin = new FileInputStream(keyStoreFile);
KeyStore keystore = KeyStore.getInstance("jks");
keystore.load(fin, keyStoreFilePassword.toCharArray());
KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(keystore, keyStoreFilePassword.toCharArray());
KeyManager[] keymanagers = kmfactory.getKeyManagers();
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keymanagers, null, null);
NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory = new SSLNHttpServerConnectionFactory(sslcontext, null, ConnectionConfig.DEFAULT);
IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(protocolHandler, connFactory);
IOReactorConfig config = IOReactorConfig.custom()
//.setIoThreadCount(10)
//.setSoTimeout(5000)
//.setConnectTimeout(4000)
//.setSoKeepAlive(true)
//.setSoReuseAddress(true)
//.setRcvBufSize(65535)
//.setTcpNoDelay(true)
.build();
ListeningIOReactor ioReactor = new DefaultListeningIOReactor(config);
ioReactor.listen(new InetSocketAddress(socketAddr, socketPort));
ioReactor.execute(ioEventDispatch);
} catch (Exception e) {
MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPSERVER.toString());
logger.error("Error while creating HTTP Server instance.", e);
}
我发现org.apache.http.protocol.responseCONTROL带有代码
if (status == HttpStatus.SC_BAD_REQUEST ||
status == HttpStatus.SC_REQUEST_TIMEOUT ||
status == HttpStatus.SC_LENGTH_REQUIRED ||
status == HttpStatus.SC_REQUEST_TOO_LONG ||
status == HttpStatus.SC_REQUEST_URI_TOO_LONG ||
status == HttpStatus.SC_SERVICE_UNAVAILABLE ||
status == HttpStatus.SC_NOT_IMPLEMENTED) {
response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
return;
}
此状态代码再现了我的问题。连接重置可能是由以下原因引起的。请尝试最新版本,看看是否解决了问题。如果响应状态为非2xx,您是否会使用消息内容?否,只有在服务器设置应答状态代码400时才会出现这种情况。我用200,401,402代码测试,正常工作。问题只存在于400个错误代码中。我必须补充一些信息:400代码的问题只存在于非空实体。若服务器并没有设置实体或设置空实体,那个么它工作正常。你们是否使用响应消息的内容?是的,我使用客户端代码为400的响应消息的内容。在客户端正确接收实体。问题只出现在服务器端的异常中。生成服务器答案的代码在我的第一篇文章的“URL Hander Code”块中。你确定吗?在您的示例代码中没有这方面的证据,只有“带有响应的一些后续操作”注释。客户端上的连接重置通常发生在客户端认为底层连接不安全,无法重复使用时,在大多数情况下,如果响应消息仍有未使用的内容,就会发生这种情况
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(20000)
.setConnectionRequestTimeout(20000)
.setSocketTimeout(20000)
.build();
SSLContext sslContext = null;
try {
TrustStrategy trustStrategy = new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) {
return true;
}
};
sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
} catch (Exception e) {
MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPCLIENT.toString());
logger.error("Error while creating SSL context for making HTTP request", e);
}
CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultRequestConfig(config)
.setSSLContext(sslContext)
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
String stringURL = "https://serverhost:port/";
try {
HttpPost post = new HttpPost(stringURL);
post.setEntity(httpClientRequest.getEntity());
CloseableHttpResponse httpResponse = client.execute(post);
// Consume entity code
HttpEntity responseEntity = httpResponse.getEntity();
String stringXMLAnswer = EntityUtils.toString(responseEntity);
EntityUtils.consume(responseEntity);
// Some next operations with responseEntity
} catch (Exception e) {
MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPCLIENT.toString());
logger.error("Error while make request.", e);
} finally {
try {
// Closing connection
client.close();
} catch (Exception e) {
MDC.put(ApplicationInit.LOGGERVAR, ApplicationInit.LOGGERCTX.HTTPCLIENT.toString());
logger.error("Error while closing connection after making request", e);
}
}
if (status == HttpStatus.SC_BAD_REQUEST ||
status == HttpStatus.SC_REQUEST_TIMEOUT ||
status == HttpStatus.SC_LENGTH_REQUIRED ||
status == HttpStatus.SC_REQUEST_TOO_LONG ||
status == HttpStatus.SC_REQUEST_URI_TOO_LONG ||
status == HttpStatus.SC_SERVICE_UNAVAILABLE ||
status == HttpStatus.SC_NOT_IMPLEMENTED) {
response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
return;
}