6

HTTP ヘッダーを含む文字列があります。これを Apache HttpComponents HttpRequest オブジェクトに変換したいと考えています。文字列を自分でバラバラにしないでこれを行う方法はありますか?

このチュートリアル: http://hc.apache.org/httpcomponents-core-dev/tutorial/html/fundamentals.html#d5e56および javadoc はそれほど多くを示していません。

4

1 に答える 1

13

文字列を 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 リクエストに変換する単純な行為と、フォームを抽出するために必要な奇妙な方法パラメータ (また、作成されたリクエストのタイプに応じて 2 つの異なる方法で実行する必要があります))。このために浪費されるグローバルな時間は膨大です。仕様から始めてボトムアップで API を記述するときは、レイヤーをトップダウンから開始する必要があります (トップは、コードの実装方法を理解したり調べたりする必要なく、典型的な作業を実行できるインターフェイスです) )、ライブラリの毎日の使用を便利で直感的にします。Apache http ライブラリは何でもありません。これ'

于 2012-05-14T10:49:29.623 に答える