2012-03-26 4 views

Antwort

13

Eine Klasse eine Zeichenfolge Apache Anfrage zu konvertieren:

import org.apache.http.*; 
import org.apache.http.impl.DefaultHttpRequestFactory; 
import org.apache.http.impl.entity.EntityDeserializer; 
import org.apache.http.impl.entity.LaxContentLengthStrategy; 
import org.apache.http.impl.io.AbstractSessionInputBuffer; 
import org.apache.http.impl.io.HttpRequestParser; 
import org.apache.http.io.HttpMessageParser; 
import org.apache.http.io.SessionInputBuffer; 
import org.apache.http.message.BasicHttpEntityEnclosingRequest; 
import org.apache.http.message.BasicLineParser; 
import org.apache.http.params.BasicHttpParams; 

import java.io.ByteArrayInputStream; 
import java.io.IOException; 

/** 
* 
*/ 
public class ApacheRequestFactory { 
    public static HttpRequest create(final String requestAsString) { 
     try { 
      SessionInputBuffer inputBuffer = new AbstractSessionInputBuffer() { 
       { 
        init(new ByteArrayInputStream(requestAsString.getBytes()), 10, new BasicHttpParams()); 
       } 

       @Override 
       public boolean isDataAvailable(int timeout) throws IOException { 
        throw new RuntimeException("have to override but probably not even called"); 
       } 
      }; 
      HttpMessageParser parser = new HttpRequestParser(inputBuffer, new BasicLineParser(new ProtocolVersion("HTTP", 1, 1)), new DefaultHttpRequestFactory(), new BasicHttpParams()); 
      HttpMessage message = parser.parse(); 
      if (message instanceof BasicHttpEntityEnclosingRequest) { 
       BasicHttpEntityEnclosingRequest request = (BasicHttpEntityEnclosingRequest) message; 
       EntityDeserializer entityDeserializer = new EntityDeserializer(new LaxContentLengthStrategy()); 
       HttpEntity entity = entityDeserializer.deserialize(inputBuffer, message); 
       request.setEntity(entity); 
      } 
      return (HttpRequest) message; 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } catch (HttpException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

und eine Test-Klasse zeigt, wie es zu benutzen:

import org.apache.http.HttpRequest; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.utils.URLEncodedUtils; 
import org.apache.http.message.BasicHttpEntityEnclosingRequest; 
import org.junit.Test; 

import java.io.IOException; 
import java.net.URI; 
import java.util.List; 

import static org.junit.Assert.*; 

/** 
* 
*/ 
public class ApacheRequestFactoryTest { 
    @Test 
    public void testGet() { 
     String requestString = "GET /?one=aone&two=atwo HTTP/1.1\n" + 
       "Host: localhost:7788\n" + 
       "Connection: Keep-Alive\n" + 
       "User-Agent: Apache-HttpClient/4.0.1 (java 1.5)"; 

     HttpRequest request = ApacheRequestFactory.create(requestString); 
     assertEquals("GET", request.getRequestLine().getMethod()); 
     List<NameValuePair> pairs = URLEncodedUtils.parse(URI.create(request.getRequestLine().getUri()), "ISO-8859-1"); 
     checkPairs(pairs); 
    } 

    @Test 
    public void testPost() throws IOException { 
     String requestString = "POST/HTTP/1.1\n" + 
       "Content-Length: 17\n" + 
       "Content-Type: application/x-www-form-urlencoded; charset=ISO-8859-1\n" + 
       "Host: localhost:7788\n" + 
       "Connection: Keep-Alive\n" + 
       "User-Agent: Apache-HttpClient/4.0.1 (java 1.5)\n" + 
       "\n" + 
       "one=aone&two=atwo"; 

     HttpRequest request = ApacheRequestFactory.create(requestString); 
     assertEquals("POST", request.getRequestLine().getMethod()); 
     List<NameValuePair> pairs = URLEncodedUtils.parse(((BasicHttpEntityEnclosingRequest)request).getEntity()); 
     checkPairs(pairs); 
    } 

    private void checkPairs(List<NameValuePair> pairs) { 
     for (NameValuePair pair : pairs) { 
      if (pair.getName().equals("one")) assertEquals("aone", pair.getValue()); 
      else if (pair.getName().equals("two")) assertEquals("atwo", pair.getValue()); 
      else assertTrue("got more parameters than expected:"+pair.getName(), false); 
     } 
    } 
} 

Und eine kleine Tirade:

WAS DAS SIND APACHE HTTP TEAM DENKEN? Die API ist unglaublich umständlich zu bedienen. Entwickler auf der ganzen Welt verschwenden Zeit mit dem Schreiben von Wrapper- und Konvertierungsklassen für das, was täglich ausgeführt werden soll (wie in diesem Beispiel die einfache Umwandlung einer Zeichenfolge in eine Apache-HTTP-Anfrage und die bizarre Art, das Formular zu extrahieren) Parameter (je nach Art der Anfrage auch auf zwei verschiedene Arten)). Die globale Zeit, die dadurch verschwendet wird, ist enorm. Wenn Sie eine API von Grund auf schreiben, beginnend mit den Spezifikationen, MÜSSEN Sie dann eine Schicht von oben nach unten starten (oben ist eine Schnittstelle, an der Sie typische Arbeit erledigen können, ohne die Art zu verstehen oder zu sehen, wie der Code implementiert wird), die den täglichen Gebrauch der Bibliothek CONVENIENT und intuitiv machen. Apache http-Bibliotheken sind alles andere als. Es ist fast ein Wunder, dass es die Standardbibliothek für diese Art von Aufgabe ist.