BLOB-изображения отображаются только при обновлении страницы после обновления через p: dataTable в PrimeFaces
Я отображаю изображения, хранящиеся в виде BLOB в MySQL на<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>
При редактировании строки<p:fileUpload>
отображается на<p:overlayPanel>
, Это и многие другие вещи опущены в этом примере для простоты, поскольку они не связаны с конкретной проблемой.
Связанный управляемый компонент JSF:
@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();
}
}
Компонент, который получает изображения из базы данных на основе уникального идентификатора строки -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
вызывается как следует.
Это правильно происходит в приложении, работающем на сервере GlassFish 4.0 с использованием PrimeFaces 5.0 и JSF 2.2.6.
Новое изображение будет отображаться в таблице данных сразу после обновления строки в таблице данных (и, следовательно, в базе данных).
На Tomcat server 8.0.5 работает другое приложение, использующее Spring 4.0.0 GA, в которомgetImage()
метод не вызывается после обновления строки, содержащейся в таблице данных, по-прежнему отображаетсястарое изображение (не недавно обновленный) в таблице данных (даже если изменения правильно передаются в базу данных).
Недавно обновленное изображение отображается только при обновлении страницы, нажавF5 (в большинстве браузеров). Он даже не отображается при загрузке страницы (введите URL-адрес в адресную строку, а затем нажмитевойти ключ).
Другими словами, когда строка в таблице данных обновляется нажатием галочки, обозначенной<p:rowEditor>
,getImage()
метод не вызывается (следовательно, новое изображение не выбирается из базы данных для отображения на<p:graphicImage>
). Этот метод вызывается только тогда, когда страница обновляется / перезагружается нажатием кнопкиF5 быстрая клавиша.
Почему это происходит? Как показать недавно обновленное изображение сразу после обновления строки?
Внешне это не должно быть связано ни с Spring, ни с JPA (операция обновления корректно распространяется на базу данных после нажатия галочки). Это скорее должно быть связано с сервером Tomcat.