2012-11-21 74 views
3

我試圖構建原始HTTP POST請求。但是,我不想實際連接到服務器併發送消息。獲取將從HttpPost發送的完整的原始HTTP請求消息

我一直在探討Apache HTTP庫,希望能夠創建一個HttpPost對象,設置實體,然後獲取它將創建的消息。到目前爲止,我可以轉儲實體,但不是整個請求,因爲它出現在服務器端。

任何想法?當然,除了重新創建輪子之外。

解決方案

我重構ShyJ的響應爲一對靜態類的,但是原來的響應工作得很好。這裏有兩類:

public static final class LoopbackPostMethod extends PostMethod { 
    private static final String STATUS_LINE = "HTTP/1.1 200 OK"; 

    @Override 
    protected void readResponse(HttpState state, HttpConnection conn) throws IOException, HttpException { 
     statusLine = new StatusLine (STATUS_LINE); 
    } 
} 

public static final class LoopbackHttpConnection extends HttpConnection { 
    private static final String HOST = "127.0.0.1"; 
    private static final int PORT = 80; 

    private final OutputStream fOutputStream; 

    public LoopbackHttpConnection(OutputStream outputStream) { 
     super(HOST, PORT); 
     fOutputStream = outputStream; 
    } 

    @Override 
    public void flushRequestOutputStream() throws IOException { /* do nothing */ } 

    @Override 
    public OutputStream getRequestOutputStream() throws IOException, IllegalStateException { 
     return fOutputStream; 
    } 

    @Override 
    public void write(byte[] data) throws IOException, IllegalStateException { 
     fOutputStream.write(data); 
    } 
} 

這裏的工廠方法,我使用了我自己的實現,作爲一個例子:

private ByteBuffer createHttpRequest(ByteBuffer data) throws HttpException, IOException { 
    LoopbackPostMethod postMethod = new LoopbackPostMethod(); 
    final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    postMethod.setRequestEntity(new ByteArrayRequestEntity(data.array())); 
    postMethod.execute(new HttpState(), new LoopbackHttpConnection(outputStream)); 
    byte[] bytes = outputStream.toByteArray(); 
    ByteBuffer buffer = ByteBuffer.allocate(bytes.length); 
    buffer.put(bytes); 
    return buffer; 
} 

回答

4

這可以通過http-client並僞造一些方法來實現。我使用http-client3.1版本。

此代碼:

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 

import org.apache.commons.httpclient.HttpConnection; 
import org.apache.commons.httpclient.HttpException; 
import org.apache.commons.httpclient.HttpState; 
import org.apache.commons.httpclient.StatusLine; 
import org.apache.commons.httpclient.methods.PostMethod; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     PostMethod method = new PostMethod() { 
      @Override 
      protected void readResponse(HttpState state, HttpConnection conn) 
        throws IOException, HttpException { 
       statusLine = new StatusLine ("HTTP/1.1 200 OK"); 
      } 
     }; 
     method.addParameter("aa", "b"); 

     method.execute(new HttpState(), new HttpConnection("http://www.google.abc/hi", 80) { 

      @Override 
      public void flushRequestOutputStream() throws IOException { 
      } 

      @Override 
      public OutputStream getRequestOutputStream() throws IOException, 
        IllegalStateException { 
       return baos; 
      } 

      @Override 
      public void write(byte[] data) throws IOException, 
        IllegalStateException { 
       baos.write(data); 
      } 

     }); 

     final String postBody = new String (baos.toByteArray()); 

     System.out.println(postBody); 
    } 
} 

將返回

POST/HTTP/1.1 
User-Agent: Jakarta Commons-HttpClient/3.1 
Host: http://www.google.abc/hi 
Content-Length: 4 
Content-Type: application/x-www-form-urlencoded 

aa=b 
1

我會做的是落實的HttpClient的接口中的一個或多個,並使用我的無操作實現。例如

請看ClientConnectionManagerAbstractHttpClient,例如。任何連接。