2012-03-26 3 views
6

HTTP 헤더가 포함 된 String이 있습니다. 이것을 Apache HttpComponents HttpRequest 객체로 바꾸고 싶습니다. 문자열을 따로 따로 선택하지 않고이 작업을 수행 할 수있는 방법이 있습니까?문자열을 Apache로 변환하는 방법 HttpRequest

이 자습서 : http://hc.apache.org/httpcomponents-core-dev/tutorial/html/fundamentals.html#d5e56 및 javadoc은 그 정도를 나타내지 않습니다.

클래스는 아파치 요청에 문자열을 변환하는

답변

13

:

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

과 사용하는 방법을 보여주는 테스트 클래스 :

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

그리고 작은 호언 장담 :

무엇인가를 APACHE HTTP 팀은 생각하고 있습니까? API는 사용하기에 대단히 어색합니다. 전 세계의 개발자들은 매일 사용량에 따라 래퍼 및 변환 클래스를 작성하는 데 시간을 낭비하고 있습니다 (이 예에서는 문자열을 Apache HTTP 요청으로 변환하는 간단한 동작과 양식 추출 작업이 필요합니다. 매개 변수 (요청의 유형에 따라 두 가지 방법으로 수행해야 함)). 이것 때문에 낭비되는 세계 시간은 엄청납니다. 스펙을 시작으로 위에서 아래로 API를 작성할 때 위에서 아래로 레이어를 시작해야합니다 (맨 위에는 코드가 구현되는 방식을 이해하거나 보지 않고도 일반적인 작업을 수행 할 수있는 인터페이스가 있어야합니다.), 매일 도서관 이용에 편리하고 직관적입니다. 아파치 http 라이브러리는 아무것도 아닙니다. 이 작업 유형을위한 표준 라이브러리 인 것은 거의 기적입니다.