Blackberry Java - 通过HTTP连接固定长度流式传输POST主体

时间:2011-06-28 16:11:34

标签: blackberry java-me

我正在研究一些代码,这些代码经常通过HTTP将大数据包发送到IIS上的REST服务器。我正在使用RIM / JavaME HTTPConnection类。

据我所知,HTTPConnection在将整个内容发送到服务器之前使用内部缓冲区来“收集”输出流。我并不感到惊讶,因为这也是HttpURLConnect默认工作的方式。 (我假设它这样做,以便正确设置内容长度。)但在JavaSE中我可以通过使用方法setFixedLengthStreamingMode覆盖此行为,以便当我在输出流上调用flush时,它将发送该“块” “流的。在手机上,这种额外的缓冲在内存方面太贵了。

在Blackberry中,当你事先知道内容长度时,有没有办法在HTTP请求上进行固定长度的流媒体?

1 个答案:

答案 0 :(得分:0)

所以,我从来没有找到过这样做的方法是HTTPConnection的基本API。所以相反,我创建了一个套接字并用我自己的简单HTTPClient包装它,它支持分块。

以下是我在BB7.0上使用和测试的原型。

package mypackage;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;

public class MySimpleHTTPClient{

    SocketConnection sc;
    String HttpHeader;
    OutputStreamWriter outWriter;
    InputStreamReader inReader;

    public void init(
            String Host, 
            String port, 
            String path, 
            int ContentLength, 
            String  ContentType ) throws IllegalArgumentException, IOException
    {
        String _host = (new StringBuffer())
                    .append("socket://")
                    .append(Host)
                    .append(":")
                    .append(port).toString();
        sc = (SocketConnection)Connector.open(_host );
        sc.setSocketOption(SocketConnection.LINGER, 5);
        StringBuffer _header = new StringBuffer();
        //Setup the HTTP Header.
        _header.append("POST ").append(path).append(" HTTP/1.1\r\n");
        _header.append("Host: ").append(Host).append("\r\n");
        _header.append("Content-Length: ").append(ContentLength).append("\r\n");
        _header.append("Content-Type: ").append(ContentType).append("\r\n");
        _header.append("Connection: Close\r\n\r\n");
        HttpHeader = _header.toString();
    }

    public void openOutputStream() throws IOException{
        if(outWriter != null) 
            return;
        outWriter = new OutputStreamWriter(sc.openOutputStream());
        outWriter.write( HttpHeader, 0 , HttpHeader.length() );
    }

    public void openInputStream() throws IOException{
        if(inReader != null) 
            return;
        inReader = new InputStreamReader(sc.openDataInputStream());
    }

    public void writeChunkToServer(String Chunk) throws Exception{
        if(outWriter == null){
            try {
                openOutputStream();
            } catch (IOException e) {e.printStackTrace();}
        } 
        outWriter.write(Chunk, 0, Chunk.length());
    }

    public String readFromServer() throws IOException {
        if(inReader == null){
            try {
                openInputStream();
            } catch (IOException e) {e.printStackTrace();}
        }
        StringBuffer sb = new StringBuffer();
        int data = inReader.read();
        //Note ::  This will also read the HTTP headers..
        // If you need to parse the headers, tokenize on \r\n for each 
        // header, the header section is done when you see \r\n\r\n
        while(data != -1){
            sb.append( (char)data  );
            data = inReader.read();
        }
        return sb.toString();
    }

    public void close(){
        if(outWriter != null){
            try {
                outWriter.close();
            } catch (IOException e) {}
        }
        if(inReader != null){
            try {
                inReader.close();
            } catch (IOException e) {}
        }
        if(sc != null){
            try {
                sc.close();
            } catch (IOException e) {}
        }
    }
}

以下是它的示例用法:

MySimpleHTTPClient myConn = new MySimpleHTTPClient() ;
String chunk1 = "ID=foo&data1=1234567890&chunk1=0|";
String chunk2 = "ID=foo2&data2=123444344&chunk1=1";
try {
    myConn.init(
            "pdxsniffe02.webtrends.corp", 
            "80",
            "TableAdd/234234234443?debug=1",
            chunk1.length() + chunk2.length(), 
            "application/x-www-form-urlencoded" 
    );

    myConn.writeChunkToServer(chunk1);
    //The frist chunk is already on it's way.
    myConn.writeChunkToServer(chunk2);
    System.out.println( myConn.readFromServer() );

} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
}finally{
    myConn.close();
}