JSF 2.2和Primefaces 4.0:文件上传后刷新图像

时间:2014-05-06 08:13:16

标签: java ajax jsf jsf-2 primefaces

在我的应用程序中,我使用JSF2.2和Primefaces 4.0。我有一个上传新图像的功能,需要更新现有图像。有时在上传新图像后,可能仍会显示旧图像,可能由于缓存或重新渲染问题而发生。我可以看到这种情况通常发生在像2500x1600这样的高分辨率图像上。这可以在IE,Chrome和Firefox中重现。以下是我的Primefaces组件:

<h:panelGroup id="mr-img-panel">
    <h:outputLink id="mr-image-link" target="_blank" process="@this"
                  value="#{myBean.image}"
                  rendered="#{myBean.image ne null}">
        <p:graphicImage id="mr-image" value="#{myBean.image}"
                        cache="false"
                        title="Title" styleClass="image-preview" />
    </h:outputLink>
</h:panelGroup>

<h:panelGroup styleClass="upload-view">
    <p:fileUpload id="mr-upload"
                  fileUploadListener="#{myBean.handleFileUpload}"
                  mode="advanced"
                  auto="true"
                  label="Upload new image"
                  dragDropSupport="true"
                  invalidFileMessage="#{msg['msg.invalid.filetype']}"
                  messageTemplate=" "
                  invalidSizeMessage="#{msg['msg.invalid.filesize']}"
                  update="mr-upload-messages, mr-img-panel"
                  sizeLimit="2097152"
                  allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
                  styleClass="upload-view-button"
                  oncomplete="setTimeout(function() { $('[id$=mr-upload-messages]').hide(1000); }, 2000);">
        <f:attribute name="someId" value="#{some.id}" />
    </p:fileUpload>

    <p:messages id="mr-upload-messages" showDetail="true" showSummary="false" closable="true"/>

起初,我认为这可能是因为缓存问题而发生的,所以我编写了一个缓存控件监听器:

public class CacheControlPhaseListener implements PhaseListener {


    @Override
    public void afterPhase(final PhaseEvent event) {

    }

    @Override
    public void beforePhase(final PhaseEvent event) {
        final FacesContext facesContext = event.getFacesContext();
        final HttpServletResponse response = (HttpServletResponse) facesContext
                .getExternalContext().getResponse();
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        // some date in the past
        response.setDateHeader("Expires", 0); // Proxies.
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }
}

但这并没有帮助。我尝试了几种不同的技术,其中一些我遇到了问题,在HERE中有描述。正如在SOLUTION中所说的那样,我写了这个FileUploadRenderer:

public class CustomFileUploadRenderer extends FileUploadRenderer {

    @Override
    public void decode(final FacesContext context, final UIComponent component) {
        if (context.getExternalContext().getRequestContentType().toLowerCase().startsWith("multipart/")) {
            super.decode(context, component);
        }
    }
}

以下是我为这些类添加到faces-config.xml的内容:

<lifecycle>
    <phase-listener id="nocache">com.example.CacheControlPhaseListener</phase-listener>
</lifecycle>

<render-kit>
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.FileUploadRenderer</renderer-type>
        <renderer-class>com.example.CustomFileUploadRenderer</renderer-class>
    </renderer>
</render-kit>

但问题仍然存在。上传新图像后,旧图像不会被AJAX刷新,只有在刷新页面后才能看到。

1 个答案:

答案 0 :(得分:1)

如果有人需要这个,似乎更新到Primefaces 5.0已经解决了这个问题。