Blackberry Java - фиксированная длина потоковой передачи тела POST через HTTP-соединение - PullRequest
0 голосов
/ 28 июня 2011

Я работаю над кодом, который часто отправляет большие пакеты по HTTP на REST-сервер в IIS. Я использую класс RIM / JavaME HTTPConnection .

Насколько я могу судить, HTTPConnection использует внутренний буфер для "сбора" выходного потока перед отправкой всего содержимого на сервер. Я не удивлен, так как именно так HttpURLConnect работает по умолчанию. (Я предполагаю, что это делается так, чтобы длина содержимого была установлена ​​правильно.) Но в JavaSE я мог переопределить это поведение, используя метод setFixedLengthStreamingMode , чтобы при вызове flush в выходном потоке он отправлял это «кусок» потока. На телефоне эта дополнительная буферизация слишком дорогая с точки зрения памяти.

В Blackberry Java есть способ сделать потоковую передачу фиксированной длины по HTTP-запросу, когда вы заранее знаете длину содержимого?

1 Ответ

0 голосов
/ 20 августа 2011

Итак, я так и не нашел способа сделать это базовым API для HTTPConnection. Вместо этого я создал сокет и обернул его своим собственным простым 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();
}
...