在我的应用程序中,我使用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刷新,只有在刷新页面后才能看到。
答案 0 :(得分:1)
如果有人需要这个,似乎更新到Primefaces 5.0已经解决了这个问题。