无法将http响应读入输入流

时间:2012-03-15 15:08:08

标签: java http blackberry

我从Blackberry应用程序调用.Net Web服务。除了KSoap2之外什么都没有问题我决定手动完成所有事情。这是一段代码:

byte [] postDataBytes = soapRequestEnvelope.getBytes();
byte [] dataRetrieved;

    try
    {
        HttpConnection connection = (HttpConnection)Connector.open(URL);

        connection.setRequestMethod(HttpConnection.POST);
        connection.setRequestProperty("soapaction", soapAction);
        connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");

        os = connection.openOutputStream();
        os.write(postDataBytes);

        int rc = connection.getResponseCode();

        if(rc == HttpConnection.HTTP_OK)
        {
            inputStream = connection.openInputStream();
            dataRetrieved = new byte[(int)connection.getLength()];
            int bytesRead = inputStream .read(dataRetrieved);

        }
        else
        {

            dataRetrieved = null;

        }


        String dataString = new String(dataRetrieved);

//HttpConnection = javax.microedition.io.HttpConnection

//inputStream = java.io.InputStream

我遇到的问题是我从Web服务调用中恢复的XML被缩短了。

当我将接收到的字节数打印到屏幕时,它有时会显示1170(这实际上是我在这种特殊情况下所期望的响应大小。)

但是其他时候收到的字节是702 ......为什么702 ???

我连续测试了十几次,得到了以下结果:

1170, 702, 1170, 1170, 702, 1170, 1170, 702, 1170, 702, 1170, 702, 702, 702, 1170, 702

但是为什么702?当它搞砸了并且不起作用时为什么它如此一致?它总是分配1170个字节,但为什么它有时只读取702 ??

这很奇怪。

编辑:我尝试将inputStream.available()打印到屏幕上进行比较,完全不一致。它在0,702和1170之间变化。有时可用字节为0或702,读取的字节数为1170.我完全糊涂了。

非常感谢任何帮助。

谢谢

2 个答案:

答案 0 :(得分:4)

在我的模糊评论之后,我想我应该通过“将read置于循环中”来指明我的意思。如defined,read将返回读取的字节数,如果到达文件末尾,则返回-1

从套接字读取时,您可能在从服务器返回所有数据之前调用read()。这样做的实际效果是,您调用read()并获得的数据少于预期。这只是意味着您需要再次(再次)再次调用它,直到获得所有数据。

我建议使用一个简单的固定大小缓冲区并循环遍历read(),直到获得-1并对每个块执行某些操作(例如,将其写入文件)。这可以防止您需要将整个文件保存在内存中。例如:

byte buf[1024];
int len;

while((len = read(buf)) >= 0)
{
    /* do something with len bytes of buf */
}

当然,您可能会保证文件很小,而且您确实希望整个内存都存在。在这种情况下,您可以(如上所述)分配connection.getLength()大小的缓冲区,但是您需要调用3-arg read(byte[], int, int)并执行更多内务处理:

int remain = (int) connection.getLength();
byte buf[remain];
int offset = 0, len;

while((len = read(buf, offset, remain)) >= 0)
{
    offset += len;
    remain -= len;
}

答案 1 :(得分:1)

网络消息以数据包形式分割。在您的情况下,整个消息需要2个数据包。 InputStream.read(byte [])读取到目前为止到达的字节数。要读取整个消息,必须进行循环,直到读取connection.getLength()字节,或者InputStream.read()返回-1。