2017-03-29 3 views
0

Obwohl die normale Verwendung für HttpClient funktioniert, habe ich Schwierigkeiten, meinen Kopf um den Connection Manager Teil zu wickeln. Weder der BasicHttpClientConnectionManager noch der PoolingHttpClientConnectionManager scheinen meinen Anwendungsfall zu erfüllen. Ich verwende einen JEE-Anwendungsserver und verwende HttpClient, um Restdienste zu nutzen.Wie verwende ich den Apache HttpClient ohne Manager?

Vom documentation:

BasicHttpClientConnectionManager ist ein einfacher Verbindungsmanager, der nur eine Verbindung zu einem Zeitpunkt hält. [...] Diese Connection Manager-Implementierung sollte in einem EJB-Container verwendet werden.

Aber ich möchte einige Pooling tun, und vorzugsweise meine eigenen Pooling (z. B. JCA-Adapter). Ich möchte einfach einen HttpClient erstellen und habe meinen eigenen separaten Pool mit HttpClients ohne den Verbindungsmanager. Irgendwelche Vorschläge oder Lösungen?

Antwort

1

Sie können nicht wirklich tun, mit Httpclient, aber Sie können mit HttpCore, Httpclient der Transport-Toolkit auf

public static void main(String[] args) throws Exception { 
    HttpProcessor httpproc = HttpProcessorBuilder.create() 
     .add(new RequestContent()) 
     .add(new RequestTargetHost()) 
     .add(new RequestConnControl()) 
     .add(new RequestUserAgent("Test/1.1")) 
     .add(new RequestExpectContinue(true)).build(); 

    HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); 

    HttpCoreContext coreContext = HttpCoreContext.create(); 
    HttpHost host = new HttpHost("localhost", 8080); 
    coreContext.setTargetHost(host); 

    DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024); 
    ConnectionReuseStrategy connStrategy = DefaultConnectionReuseStrategy.INSTANCE; 

    try { 

     String[] targets = { 
       "/", 
       "/servlets-examples/servlet/RequestInfoExample", 
       "/somewhere%20in%20pampa"}; 

     for (int i = 0; i < targets.length; i++) { 
      if (!conn.isOpen()) { 
       Socket socket = new Socket(host.getHostName(), host.getPort()); 
       conn.bind(socket); 
      } 
      BasicHttpRequest request = new BasicHttpRequest("GET", targets[i]); 
      System.out.println(">> Request URI: " + request.getRequestLine().getUri()); 

      httpexecutor.preProcess(request, httpproc, coreContext); 
      HttpResponse response = httpexecutor.execute(request, conn, coreContext); 
      httpexecutor.postProcess(response, httpproc, coreContext); 

      System.out.println("<< Response: " + response.getStatusLine()); 
      System.out.println(EntityUtils.toString(response.getEntity())); 
      System.out.println("=============="); 
      if (!connStrategy.keepAlive(response, coreContext)) { 
       conn.close(); 
      } else { 
       System.out.println("Connection kept alive..."); 
      } 
     } 
    } finally { 
     conn.close(); 
    } 

Der Beispielcode von here

+0

Interessante genommen basiert. Das Problem, das ich habe, ist, dass ich einen echten httpclient haben möchte, damit ein Framework wie Spring Resttemplate es benutzen kann. Ich kann nicht sehen, wie das in diesem Fall funktionieren würde. – user1120821

+0

Es gibt nichts, das daran gehindert wird, CloseableHttpClient zu erweitern und seine #doExecute-Methode nach Belieben zu implementieren. Die einzige nicht-triviale Aufgabe wäre wahrscheinlich, CloseableHttpResponse zu implementieren und die ordnungsgemäße Freigabe der zugrunde liegenden Verbindung zu gewährleisten, die dem Antwortstream – oleg

+0

zugeordnet ist. So könnten wir doExecute an den HttpRequestExecutor delegieren und die Antwort in unserem eigenen HttpResponseProxy umbrechen. Außerdem müsste ich etwas mit ssl-Verbindungen machen, aber ich kann sehen, worauf Sie hinauswollen. Vielen Dank! – user1120821

Verwandte Themen