使用执行程序服务时如何使用jsf添加消息?

时间:2013-06-18 13:46:10

标签: jsf-2 primefaces

我想在线程中发生异常时在浏览器中显示友好的错误消息。我在xhtml页面中有(类似于h:message)。它只显示来自同一线程的消息,但在此方案中不起作用。如何在不保存线程的情况下使其工作,因为该方法应该异步执行?

public void start(final Land lan)
    {
        try {
            Future future = executor.submit(new Callable(){
                @Override
                public Object call() {
                    try {
                        conversion.processLand(lan);
                        LOG.debug("Finished the execution serverion");
                        uploadLandPages(lan.getPages(),
                                lan.getLandOID());
                    }catch(LanException doc){
                        LOG.error("LanException is caused due to "+doc.getMessage());
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"File Conversion Issue","Unfortunately we cannot convert this file, please try again later"));
                    } catch (ApplicationException apx) {
                        LOG.error("ApplicationException is caused due to "+apx.getMessage());
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"File Conversion Issue", "We have successfully converted the file but couldn't save in our server"));
                    }

                    return null;
                }
            });
        } catch(Exception e){
            LOG.error("Exception caused in the thread which converts the doc due to {}",e.getMessage());
            throw new RuntimeException("Couldn't create the Conversion thread");
        }
            finally {
            executor.shutdown();
        }
    }

1 个答案:

答案 0 :(得分:3)

它不起作用,因为消息必须进入HTTP响应。当您将服务于HTTP请求的线程保留为异步运行时,您显然会失去对HTTP响应的控制权。更重要的是,FacesContext在其他线程中根本不可用。特定代码只会以NullPointerException结尾。

你基本上有两种选择:

  1. 使用投票。您可以使用<p:poll>。只要存在非空消息,就会间隔轮询到会话范围的bean。然后删除并显示它并停止轮询。执行程序服务应将消息设置为该会话作用域bean的属性。

  2. 使用推送。您可以使用<p:socket> (PrimePush)。执行者应通过PushContext#push()<p:socket channel>标识的唯一渠道名称上设置消息(当前用户独有!或者可能反映给所有用户)。


  3. 无关具体问题,因为您似乎已经在使用Java EE,我建议使用@Asynchronous EJB方法而不是执行服务,如果可能的话。这样线程就由容器本身管理和汇集。