【问题标题】:How to convert a string to an Apache HttpComponents HttpRequest如何将字符串转换为 Apache HttpComponents HttpRequest
【发布时间】:2012-03-26 21:26:22
【问题描述】:

我有一个包含 HTTP 标头的字符串。我想把它变成一个 Apache HttpComponents HttpRequest 对象。有没有办法在不自己拆线的情况下做到这一点?

本教程:http://hc.apache.org/httpcomponents-core-dev/tutorial/html/fundamentals.html#d5e56 和 javadoc 并没有说明那么多。

【问题讨论】:

    标签: apache-httpcomponents


    【解决方案1】:

    一个将字符串转换为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);
            }
        }
    }
    

    以及一个展示如何使用它的测试类:

    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 时,从规范开始,您必须然后从上往下开始一层(顶层是一个接口,您可以在其中完成典型工作,而无需了解或查看代码的实现方式),使图书馆的日常使用变得方便和直观。 Apache http 库不过如此。它成为此类任务的标准库几乎是一个奇迹。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2018-04-30
      • 2014-05-26
      • 1970-01-01
      相关资源
      最近更新 更多