2012-03-26 4 views

Respuesta

13

Una clase para convertir una cadena a petición de Apache:

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); 
     } 
    } 
} 

y una clase de ensayo que muestra cómo usarlo:

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); 
     } 
    } 
} 

y una pequeña queja:

¿QUÉ SON LOS APACHE HTTP TEAM PENSAMIENTO? La API es increíblemente incómoda de usar. Los desarrolladores de todo el mundo están perdiendo el tiempo escribiendo envoltorios y clases de conversión para lo que debería ejecutarse diariamente (como en este ejemplo, el simple acto de convertir una cadena a una solicitud http apache, y la forma extraña en que necesita extraer el formulario parámetros (que también tienen que hacerlo de dos maneras diferentes según el tipo de solicitud que se haya hecho)). El tiempo global perdido debido a esto es enorme. Cuando escribes una API de abajo hacia arriba, comenzando con las especificaciones, DEBES comenzar una capa de arriba hacia abajo (la parte superior es una interfaz donde puedes realizar el trabajo típico sin tener que entender o mirar la forma en que se implementa el código)), haciendo que el uso diario de la biblioteca sea CONVENIENTE e intuitivo. Las bibliotecas http de Apache son cualquier cosa menos. Es casi un milagro que sea la biblioteca estándar para este tipo de tareas.