如何连续地将文本数据流式传输到servlet?

时间:2012-07-13 10:49:30

标签: java-ee servlets streaming

我有一个Android应用程序连接到服务器并连续发送一些信号数据(使用HttpURLConnection)。在服务器上,脚本(shell或python,不完全知道,它不是我的部分)当前处理此流,并且每个incomming数据包都设置curl请求以将此包发布到servlet(在Jetty 8 web中运行)容器)。这只是一个临时解决方案,因为我不知道如何直接连接数据并将数据流传输到servlet。根据要求,数据传输应使用HTTP协议,以免被任何防火墙阻止。

那么,是否可以初始连接到servlet,然后长时间(例如几分钟或几小时)流式传输数据?我想知道我没有找到类似的问题/解决方案。我的意思是这不是一个特殊的场景。这与将大文件上传到servlet的操作相同吗?

servlet实际上是这样的:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
    System.out.println("StreamingServlet#doPost(): IN");
    BufferedReader reader = request.getReader();
    String data = "";

    while ((data = reader.readLine()) != null)
    {
        System.out.println("Data: " + data);
    }
    reader.close();

    System.out.println("StreamingServlet#doPost(): OUT");
}

Android应用程序有3个方法使用HttpURLConnection:

private Boolean connect(URL URLdest)
{
    try
    {
        connection = (HttpURLConnection) URLdest.openConnection();
        connection.setDoOutput(true);
        connection.setChunkedStreamingMode(0);
        oSWout = new OutputStreamWriter(connection.getOutputStream());
    }
    catch (IOException e)
    {
        return false;
    }
    return true;
}   

public void send(String packet)
{
    try
    {
        // TODO clOSWout.write and clOSWout.flush block may freeze if connection is lost. Somehow no exception is thrown and thread hangs instead.
        // It only occurs if the Server breaks the connection

        oSWout.write(packet);
        oSWout.flush();
    }
    catch (IOException e)
    {
        ...
    }
}

public void stopConnection()
{
    try
    {
        oSWout.close();
        connection.disconnect();
    }
    catch (IOException e)
    {
        ...
    }
}

我最终期望的是,当连接到servlet时,它打印“StreamingServlet#doPost():IN”,然后,对于每个incomming数据包,它应该打印数据字符串,当关闭连接时,它应该打印“StreamingServlet #doPost():OUT”,最后从方法返回。

但我想我错过了一些东西,这在Java EE中以另一种方式完成。我不知道。

1 个答案:

答案 0 :(得分:2)

最后,我自己解决了这个问题:

使用BufferedReader,收集(缓冲)所有数据包,并在连接关闭时作为一个包装进行读取和打印。所以我不得不使用ServletInputStream [由HttpServletRequest#getInputStream()获取]并使用read()方法将数据包读入字节数组。现在一切都按照我的预期运作。

但我仍然想知道,如果使用阻塞操作或多或少的典型场景,因此在doPost()方法中保持很长时间(比如几分钟或几小时),或者如果服务器以某种方式预期响应更短的时间。