为什么在JSF动作调用之间出现一个desfase?

时间:2014-11-19 18:31:12

标签: java jsf primefaces liferay portlet

我在Liferay 6.2的portlet应用程序中工作,使用primefaces 3.5,它是一种文档浏览器。文档显示在datagrig中,每个元素都是一个链接,用于在新浏览器选项卡中打开内容。

我目前的代码有效,但有一个很大的错误。首先clic不打开文档,在新选项卡中打开portlet的html片段,第二次打开前一个。更清楚:

  • 步骤1:文件A中的clic =打开html
  • 步骤2:文件B中的clic =打开文件A
  • 步骤3:文件C中的clic =打开文件B
  • 等......

我认为它不是和执行顺序问题,因为日志从第一个clic开始打印所选文档的正确信息

这是view.xhtml片段

<h:form>
    <p:dataGrid var="document" value="#{documentBean.documents}" columns="5" rows="15">
        <p:column>
            <h:commandLink action="#{documentBean.openDocument}" target="_blank">
                <f:setPropertyActionListener target="#{documentBean.selectedDocument}" value="#{document}" />
                <p:fileDownload value="#{documentBean.content}" contentDisposition="inline" />
                <h:outputText value="Open Document" />
            </h:commandLink>
        </p:column>
    </p:dataGrid>
</h:form>

这是mange bean最相关的部分

@ManagedBean(name = "documentBean")
@ViewScoped
public class DocumentBean {

private List<DocumentVO> documents;
private DocumentVO selectedDocument;
private StreamedContent content;

@EJB
private DocumentServiceIntegrator documentIntegrator;
private static final Log LOG = LogFactory.getLog(DocumentBean.class);

@PostConstruct
public void init() {
    documents = documentIntegrator.getFolderContentByPath("/");
    selectedDocument = new DocumentVO();
}

public String openDocument() {
    LOG.info("Open document: " + selectedDocument.getId() + " (" + selectedDocument.getName() + ", " + selectedDocument.getMimeType() + ")");
    byte[] bytes = documentIntegrator.getDocumentContentById(selectedDocument.getId());
    LOG.info("Document content: " + (bytes != null ? bytes.length + " bytes" : "null"));
    InputStream stream = new ByteArrayInputStream(bytes);
    content = new DefaultStreamedContent(stream, selectedDocument.getMimeType(), selectedDocument.getName());
    return null;
}

// getters and setters for: documents, selectedDocument and content

}

关于发生了什么以及如何解决它的任何想法?

由于

1 个答案:

答案 0 :(得分:0)

我找到了一种解决方法,在view.xhtml中,我删除了 h:commandLink action 属性,并在之后添加了 f:actionListener 标记 f:setPropertyActionListener (订单很重要)

<h:commandLink target="_blank">
    <f:setPropertyActionListener target="#{documentBean.selectedDocument}" value="#{document}" />
    <f:actionListener binding="#{documentBean.openDocumentActionListener}" />
    <p:fileDownload value="#{documentBean.content}" contentDisposition="inline" />
    <h:outputText value="Open Document" />
</h:commandLink>

在manage bean中,我使用StreamedContent创建逻辑

创建了自定义ActionListener
@ManagedBean(name = "documentBean")
@ViewScoped
public class DocumentBean {

private List<DocumentVO> documents;
private DocumentVO selectedDocument;
private StreamedContent content;
private ActionListener openDocumentActionListener;

@EJB
private DocumentServiceIntegrator documentIntegrator;
private static final Log LOG = LogFactory.getLog(DocumentBean.class);

@PostConstruct
public void init() {
    documents = documentIntegrator.getFolderContentByPath("/");
    selectedDocument = new DocumentVO();
    openDocumentActionListener = createOpenDocumentActionListener();
}

public ActionListener createOpenDocumentActionListener() {
    ActionListener actionListener = new ActionListener() {
        @Override
        public void processAction(ActionEvent arg0) throws AbortProcessingException {
            LOG.info("Open document: " + selectedDocument.getId() + " (" + selectedDocument.getName() + ", " + selectedDocument.getMimeType() + ")");
            byte[] bytes = documentIntegrator.getDocumentContentById(selectedDocument.getId());
            LOG.info("Document content: " + (bytes != null ? bytes.length + " bytes" : "null"));
            InputStream stream = new ByteArrayInputStream(bytes);
            content = new DefaultStreamedContent(stream, selectedDocument.getMimeType(), selectedDocument.getName());
        }
    };
    return actionListener;
}

// getters and setters for: documents, selectedDocument, content and openDocumentActionListener

}

在我不知道对象内容的情况下发生的事情似乎是在它已经创建或准备之前在动作中下载。

希望这有帮助的人,我不知道如何谷歌。