Java 将内容流式传输到JSF UI

Java 将内容流式传输到JSF UI,java,jsf,Java,Jsf,我非常满意我的JSF应用程序,它读取接收到的MQ消息的内容并将它们提供给UI,如下所示: <rich:panel> <snip> <rich:panelMenuItem label="mylabel" action="#{MyBacking.updateCurrent}"> <f:param name="current" value="mylog.log" /> </rich:panelMenuItem> &l

我非常满意我的JSF应用程序,它读取接收到的MQ消息的内容并将它们提供给UI,如下所示:

<rich:panel>
<snip>
  <rich:panelMenuItem label="mylabel"  action="#{MyBacking.updateCurrent}">
    <f:param name="current" value="mylog.log" />    
  </rich:panelMenuItem>
</snip>
</rich:panel>

<rich:panel>
  <a4j:outputPanel ajaxRendered="true">
    <rich:insert content="#{MyBacking.log}" highlight="groovy" />
  </a4j:outputPanel>
</rich:panel>
直到其中一条消息的内容太大,tomcat掉了下来。显然,我认为,我需要改变它的工作方式,以便返回某种形式的流,这样就不会有一个对象变得太大,以至于容器死亡,并且连续消息返回的内容在传入时流式传输到UI

我认为我可以用一个
BufferedOutputStream
对象替换我现在在
String
对象上所做的工作,也就是说,JSF代码没有变化,后端也有类似的变化:

private BufferedOutputStream logFile = null;

    public void setLog(String log) {
        sendMsg(args);
        logFile = (BufferedOutputStream) receiveMsg(moreargs); 
    }

    public String getLog() {
        return logFile;
    }

如果Tomcat超过这个值,那么它的大小必须超过128MB,或者可能是两倍(这是某些Tomcat版本的最小默认内存大小)。我不认为用户会重视访问这么大的网页。在本地主机上同时充当服务器和客户端时,它的速度可能会很快,但在Internet上服务时,速度会慢100倍

引入分页/过滤。一次查询并显示大约100个条目。添加一个返回特定结果的筛选器,例如特定时间范围或特定用户的日志等

谷歌也不会一次在一个网页上显示所有的可用结果,他们的服务器肯定也会“倒下”:

根据注释更新:bean是否已放入会话范围内?这样它很快就会在记忆中积累起来。只有在一侧有一个
InputStream
,另一侧有一个
OutputStream
时,才能进行流式处理。在进行强制转换时,无法将字符串转换为流,这样就不会再将其存储在Java内存中。源必须留在另一端,并且必须通过行逐字节检索。唯一可行的方法是使用一个
,它的
src
指向一些
HttpServlet
,直接将数据从源流传输到响应


您的最佳选择可能是将整个内容存储在数据库中,或者(如果它不包含特定于用户的数据)存储在应用程序范围中,并在所有会话/请求之间共享。

如果Tomcat超过了这一点,那么它的大小必须超过128MB,或者可能是两倍(这是某些Tomcat版本的最小默认内存大小)。我不认为用户会重视访问这么大的网页。在本地主机上同时充当服务器和客户端时,它的速度可能会很快,但在Internet上服务时,速度会慢100倍

引入分页/过滤。一次查询并显示大约100个条目。添加一个返回特定结果的筛选器,例如特定时间范围或特定用户的日志等

谷歌也不会一次在一个网页上显示所有的可用结果,他们的服务器肯定也会“倒下”:

根据注释更新:bean是否已放入会话范围内?这样它很快就会在记忆中积累起来。只有在一侧有一个
InputStream
,另一侧有一个
OutputStream
时,才能进行流式处理。在进行强制转换时,无法将字符串转换为流,这样就不会再将其存储在Java内存中。源必须留在另一端,并且必须通过行逐字节检索。唯一可行的方法是使用一个
,它的
src
指向一些
HttpServlet
,直接将数据从源流传输到响应


您的最佳选择可能是将整个内容存储在数据库中,或者(如果它不包含特定于用户的数据)存储在应用程序范围中,并在所有会话/请求中共享。

谢谢您的建议,但我的用户是内部的,不基于internet。然而,我确实将Tomcat设置为默认memsize,事实上,一条消息(远小于128MB)导致该问题提醒我,可能有多个用户请求这样大小的文件,所有用户都希望获得整个文件,并使用浏览器的“查找”功能搜索特定字符串以解决问题。我曾考虑过分页,但实际上这是最后的选择。我认为流媒体比文本搜索工具更简单。@BalusC re-update:重新考虑我将要做的解决方案似乎是合乎逻辑的。我希望将bean保持在会话范围内,尽管我可以使用输出流读取MQ队列(如果文件非常大),但浏览器会坐在那里搅动。我宁愿提供更方便用户的方法。谢谢你的建议,但我的用户是内部的,不是基于互联网的。然而,我确实将Tomcat设置为默认memsize,事实上,一条消息(远小于128MB)导致该问题提醒我,可能有多个用户请求这样大小的文件,所有用户都希望获得整个文件,并使用浏览器的“查找”功能搜索特定字符串以解决问题。我曾考虑过分页,但实际上这是最后的选择。我认为流媒体比文本搜索工具更简单。@BalusC re-update:重新考虑我将要做的解决方案似乎是合乎逻辑的。我希望将bean保持在会话范围内,尽管我可以使用输出流读取MQ队列(如果文件非常大),但浏览器会坐在那里搅动。我宁愿提供更方便用户的方法。谢谢
private BufferedOutputStream logFile = null;

    public void setLog(String log) {
        sendMsg(args);
        logFile = (BufferedOutputStream) receiveMsg(moreargs); 
    }

    public String getLog() {
        return logFile;
    }