我在 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>
While editing of a row, a <p:fileUpload>
is displayed on a <p:overlayPanel>
. This and many other things are omitted in this example for the sake of simplicity as they are not related to the concrete problem.
关联的 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 上运行的应用程序,其中the getImage()
方法未被调用更新数据表保存的行后,仍然显示旧图像(不是新更新的)在数据表中(即使更改已正确传播到数据库)。
The newly updated image is displayed only when the page refreshed by pressing F5 (on most browsers). It is even not displayed on page load (entering a URL into the address bar and then pressing the enter key).
In other words, when a row in a data table is updated by clicking the tick indicated by <p:rowEditor>
, the getImage()
method is not invoked (hence, the new image is not fetched from the database to be displayed on <p:graphicImage>
). This method is invoked only when the page is refreshed/reloaded by pressing the F5 shortcut key.
为什么会出现这种情况?如何在更新一行后立即显示新更新的图像?
表面上看,这应该与 Spring 或 JPA 无关(点击勾号后更新操作正确传播到数据库)。这应该与 Tomcat 服务器有关。