当用户取消文件下载时,FacesMessage未显示在p:消息中

时间:2015-06-18 13:34:01

标签: jsf primefaces download jsf-2.2 cancellation

当我在try-catch的catch块中添加FacesMessage时,它不会显示在p:messages组件中。如果我在另一个位置添加FacesMessage,则会显示。为什么呢?

添加FacesMessage

try {
    ...
} catch (ServiceException | IOException e) {
    LOG.error("Failed to load content for download", e);
    MessageUtils.addErrorMessage(msgs, "msg.error.general", (Object[]) null);
}


public static void addErrorMessage(final MessagesProxy msgs, final String key, final Object... params)
{
    final FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msgs.getText(key, params), null);
    final FacesContext fc = FacesContext.getCurrentInstance();
    fc.addMessage(null, msg);
    fc.validationFailed();
}

msgs是对资源包的访问。

以下是p:messages autoUpdate=true

<p:messages id="mainMessagesId" autoUpdate="true" />

背景:ui提供了在辅助bean中处理的文件下载。如果用户选择一个大文件并在浏览器的另存为对话框中单击按钮取消,则会出现异常:

15:29:13,599 ERROR [xxx.web.bl.ContentBL] (http-/127.0.0.1:9090-1) Failed to load content for download: ClientAbortException:  java.net.SocketException: Connection reset by peer: socket write error
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:403) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:450) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:351) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:426) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:415) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
at org.omnifaces.servlet.GzipHttpServletResponse$GzipThresholdOutputStream.write(GzipHttpServletResponse.java:204) [omnifaces-1.8.1.jar:1.8.1-20140603]
at org.omnifaces.io.ResettableBufferedOutputStream.write(ResettableBufferedOutputStream.java:77) [omnifaces-1.8.1.jar:1.8.1-20140603]
at org.omnifaces.io.ResettableBufferedOutputStream.write(ResettableBufferedOutputStream.java:56) [omnifaces-1.8.1.jar:1.8.1-20140603]
at org.omnifaces.servlet.HttpServletResponseOutputWrapper$1.write(HttpServletResponseOutputWrapper.java:92) [omnifaces-1.8.1.jar:1.8.1-20140603]
at java.io.OutputStream.write(OutputStream.java:116) [rt.jar:1.7.0_75]
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1793) [commons-io-2.4.jar:2.4]
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769) [commons-io-2.4.jar:2.4]
at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744) [commons-io-2.4.jar:2.4]
at xxx.web.bl.ContentBL.downloadContent(ContentBL.java:309) [classes:]
at xxx.web.bl.ContentBL$Proxy$_$$_WeldClientProxy.downloadContent(ContentBL$Proxy$_$$_WeldClientProxy.java) [classes:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_75]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_75]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_75]
at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_75]
at javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:735) [jboss-el-api_2.2_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
at javax.el.BeanELResolver.invoke(BeanELResolver.java:467) [jboss-el-api_2.2_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:246) [jboss-el-api_2.2_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
at de.odysseus.el.tree.impl.ast.AstMethod.eval(AstMethod.java:91) [juel-impl-2.2.7.jar:2.2.7]
at de.odysseus.el.tree.impl.ast.AstMethod.invoke(AstMethod.java:104) [juel-impl-2.2.7.jar:2.2.7]
at de.odysseus.el.tree.impl.ast.AstEval.invoke(AstEval.java:71) [juel-impl-2.2.7.jar:2.2.7]
at de.odysseus.el.TreeMethodExpression.invoke(TreeMethodExpression.java:132) [juel-impl-2.2.7.jar:2.2.7]
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) [weld-core-1.1.16.Final-redhat-1.jar:1.1.16.Final-redhat-1]
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) [weld-core-1.1.16.Final-redhat-1.jar:1.1.16.Final-redhat-1]
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) [jsf-impl-2.2.11.jar:2.2.11]
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87) [jsf-api-2.2.11.jar:2.2]
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) [jsf-impl-2.2.11.jar:2.2.11]
at org.apache.myfaces.extensions.cdi.jsf.impl.security.SecurityViolationAwareActionListener.processAction(SecurityViolationAwareActionListener.java:56) [myfaces-extcdi-jsf20-module-impl-1.0.5.jar:1.0.5]
at org.apache.myfaces.extensions.cdi.jsf.impl.config.view.ViewControllerActionListener.processAction(ViewControllerActionListener.java:68) [myfaces-extcdi-jsf20-module-impl-1.0.5.jar:1.0.5]
at org.apache.myfaces.extensions.cdi.jsf.impl.listener.action.CodiActionListener.processAction(CodiActionListener.java:58) [myfaces-extcdi-jsf20-module-impl-1.0.5.jar:1.0.5]
at org.omnifaces.eventlistener.ResetInputAjaxActionListener.processAction(ResetInputAjaxActionListener.java:197) [omnifaces-1.8.1.jar:1.8.1-20140603]
at javax.faces.component.UICommand.broadcast(UICommand.java:315) [jsf-api-2.2.11.jar:2.2]

然后p:messages没有显示任何内容。 我正在使用primefaces 5.2.6和JSF 2.2.11。

此致 奥利弗

1 个答案:

答案 0 :(得分:4)

即使最终用户尚未决定是将文件保存在指定位置还是取消文件下载,大多数现代浏览器都已经在后台下载文件。取消显然会中止当前运行的下载请求。如果文件的下载速度比最终用户决定取消的速度快,那么服务器完全不会注意到它,浏览器会默默地从(临时)磁盘中删除它而不是移动/重命名它。

这种异常不能在服务器端以向最终用户显示消息的形式处理,原因很简单,因为不再有请求/响应的方法。客户端已中止请求/响应。在任何地方都没有回复来写消息。您最好的选择是推送连接(例如,通过PrimeFaces <p:socket>的websockets)。

让异常消失。客户拥有一切。如有必要,请禁止特定ClientAbortException的日志记录,以免您在服务器日志中受到打扰。

另见:

无关具体问题,根据您使用OmniFaces的堆栈跟踪。如果您还不知道它,它会MessageUtils<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="utf-8"/> <xsl:strip-space elements="*"/> <xsl:template match="/orders"> <xsl:text>Customer, Name, Price, Code&#10;</xsl:text> <xsl:apply-templates select="order/items/item"/> </xsl:template> <xsl:template match="item"> <xsl:value-of select="../../customer"/> <xsl:text>, </xsl:text> <xsl:apply-templates/> <xsl:if test="position()!=last()"> <xsl:text>&#10;</xsl:text> </xsl:if> </xsl:template> <xsl:template match="item/*"> <xsl:value-of select="."/> <xsl:if test="position()!=last()"> <xsl:text>, </xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet> 样板文件中保存{/ 3}。