我在 MySQL 中显示以 BLOB 形式存储的图像<p:graphicImage>
,如下所示。
<p:dataTable var="row" value="#{testManagedBean}" lazy="true" editable="true" rows="10">
<p:column headerText="id">
<h:outputText value="#{row.brandId}"/>
</p:column>
<p:column headerText="Image">
<p:cellEditor>
<f:facet name="output">
<p:graphicImage value="#{brandBean.image}" height="100" width="100">
<f:param name="id" value="#{row.brandId}"/>
</p:graphicImage>
</f:facet>
<f:facet name="input">
<p:graphicImage id="image" value="#{brandBean.image}" height="100" width="100">
<f:param name="id" value="#{row.brandId}"/>
</p:graphicImage>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit" width="50">
<p:rowEditor/>
</p:column>
</p:dataTable>
编辑行时,a<p:fileUpload>
上会显示 a <p:overlayPanel>
。为简单起见,本示例中省略了这一点和许多其他内容,因为它们与具体问题无关。
关联的 JSF 托管 bean:
@ManagedBean
@ViewScoped
public final class TestManagedBean extends LazyDataModel<Brand> implements Serializable
{
@EJB
private final TestBeanLocal service=null;
private static final long serialVersionUID = 1L;
@Override
public List<Brand> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
setRowCount(3);
return service.getList();
}
}
基于唯一行标识符从数据库中检索图像的 bean - BrandBean
.
@ManagedBean
@ApplicationScoped
public final class BrandBean
{
@EJB
private final BrandBeanLocal service=null;
public BrandBean() {}
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
}
else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
System.out.println("id = "+id);
byte[] bytes = service.findImageById(Long.parseLong(id));
return bytes==null? new DefaultStreamedContent(new ByteArrayInputStream(new byte[0])):new DefaultStreamedContent(new ByteArrayInputStream(bytes));
}
}
}
<p:rowEditor>
当通过单击位于数据表最后一列(由 指示)中的对勾来更新(在编辑之后)行时,将按应有的方式调用 中的getImage()
方法。BrandBean
这在使用 PrimeFaces 5.0 和 JSF 2.2.6 在 GlassFish server 4.0 上运行的应用程序中正确发生。
在数据表(以及数据库中)更新一行后,新图像将立即显示在数据表中。
还有另一个使用 Spring 4.0.0 GA 在 Tomcat 服务器 8.0.5 上运行的应用程序,其中在更新数据表保存的行后未调用该getImage()
方法,导致仍然显示旧图像(不是新更新的图像)在数据表(即使更改已正确传播到数据库)。
F5仅当按下(在大多数浏览器上)刷新页面时,才会显示新更新的图像。它甚至不会在页面加载时显示(在地址栏中输入 URL,然后按enter键)。
换句话说,当通过单击 表示的勾号更新数据表中的行时,不会调用<p:rowEditor>
该getImage()
方法(因此,不会从数据库中获取新图像以显示在 上<p:graphicImage>
)。该方法仅在通过F5快捷键刷新/重新加载页面时调用。
为什么会这样?如何在更新一行后立即显示新更新的图像?
从表面上看,这应该与 Spring 和 JPA 无关(点击勾选后更新操作正确传播到数据库)。这应该与Tomcat服务器有关。