Jsf 在PrimeFaces中通过p:dataTable进行更新后,BLOB图像仅显示在刷新页面上
我正在一个Jsf 在PrimeFaces中通过p:dataTable进行更新后,BLOB图像仅显示在刷新页面上,jsf,tomcat,primefaces,jsf-2.2,graphicimage,Jsf,Tomcat,Primefaces,Jsf 2.2,Graphicimage,我正在一个上显示MySQL中以BLOB形式存储的图像,如下所示 <p:dataTable var="row" value="#{testManagedBean}" lazy="true" editable="true" rows="10"> <p:column headerText="id"> <h:outputText value="#{row.brandId}"/> </p:column> <p:
上显示MySQL中以BLOB形式存储的图像,如下所示
<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>
当通过单击数据表最后一列中的勾号(由
指示)来更新行(编辑后),就会调用BrandBean
中的getImage()
方法
这在使用PrimeFaces 5.0和JSF 2.2.6的GlassFish服务器4.0上运行的应用程序中是正确的
数据表(以及数据库)中的行更新后,新图像将立即显示在数据表中
另一个应用程序运行在Tomcat server 8.0.5上,使用Spring 4.0.0 GA,在更新数据表中的一行后,不会调用
getImage()
方法,从而在数据表中仍然显示旧图像(不是新更新的图像)(即使更改已正确传播到数据库)
仅当按F5刷新页面时(在大多数浏览器上),才会显示新更新的图像。在页面加载时,甚至不会显示新更新的图像(在地址栏中输入URL,然后按enter键)
换句话说,当通过单击
指示的勾号来更新数据表中的行时,不会调用getImage()
方法(因此,不会从数据库中提取新图像以显示在
上)。仅当按F5快捷键刷新/重新加载页面时才会调用此方法
为什么会发生这种情况?如何在行更新后立即显示新更新的图像 表面上看,这不应该与Spring或JPA相关(在点击勾号后更新操作被正确地传播到数据库),而应该与Tomcat服务器相关 仅当按F5刷新页面时(在大多数浏览器上),才会显示新更新的图像。在页面加载时,甚至不会显示新更新的图像(在地址栏中输入URL,然后按enter键) webbrowser正在缓存映像。资源通过响应标头中设置的缓存相关指令以每个URL为基础进行缓存。导致您的具体问题的原因是资源URL仍然相同,并且webbrowser不知道服务器端的资源已更改。详细说明了缓存(注意:过滤器不是此问题的解决方案) 基本上,您需要通过更改URL来强制webbrowser重新请求资源。对于这种情况,最常见的方法之一是在“上次修改”之后添加“上次修改”,即突然更改可缓存资源,并立即将其更改反映到所有客户端将图像的时间戳添加到URL的查询字符串。如果您使用的是JPA,那么应该这样做:
- 将
列添加到lastModified
表中:brand
ALTER TABLE brand ADD COLUMN lastModified TIMESTAMP DEFAULT now();
- 使用适当的属性和设置该属性的属性扩展
实体:品牌
(JPA在每次@Column @Temporal(TemporalType.TIMESTAMP) private Date lastModified; @PreUpdate public void onUpdate() { lastModified = new Date(); } // +getter+setter
查询之前调用更新
带注释的方法)@PreUpdate
- 将其附加到图像URL(参数名称
是对“版本”的提示):v
品牌时更新,则将其拆分到另一个表图像
,并让品牌
有一个FK(@ManyToOne
或@oone
)到图像
。这也使属性成为“图像”可在webapp中的各种实体之间重用。hy
我也有同样的问题,但是我的镜像src在硬盘中,而不是在DB中。
当我使用了一个随机数,但我不读它时,我就产生了这个问题。
一般来说,当这个参数是一个随机数时,我会在src映像中添加一个参数
我的解决方案如下:
public class UserPage {
private String fotoCVPath;
//all variabile
private String getRandomImageName() {
int i = (int) (Math.random() * 10000000);
return String.valueOf(i);
}
public void editImage() {
//init the fotoCVPath
fotoCVPath = fotoCVPath + "?tmpVal=" + getRandomImageName();
}
/**
* @return the fotoCVPath <br>
*
* @author - asghaier <br>
*
* Created on 29/mag/2014
*/
public String getFotoCVPath() {
return fotoCVPath;
}
/**
* @param fotoCVPath the fotoCVPath to set <br>
*
* @author- asghaier <br>
*
* Created on 29/mag/2014
*/
public void setFotoCVPath(String fotoCVPath) {
this.fotoCVPath = fotoCVPath;
}
}
<h:panelGrid ...al param >
<h:column>
<p:graphicImage id="imgCV" value="#{userPage.fotoCVPath}" styleClass="imgCVStyle" />
</h:column>
</h:panelGrid>
公共类用户页{
私有字符串fotoCVPath;
//全可变
私有字符串getRandomImageName(){
int i=(int)(Math.random()*10000000);
返回字符串.valueOf(i);
}
public void editImage(){
//初始化fotoCVPath
fotoCVPath=fotoCVPath+“?tmpVal=“+getRandomImageName();
}
/**
*@返回fotoCVPath
*
*@author-asghaier
*
*创建于2014年6月29日
*/
公共字符串getFotocPath(){
返回fotoCVPath;
}
/**
*@param fotoCVPath要设置的fotoCVPath
*
*@author-asghaier
*
*创建于2014年6月29日
*/
公共void setFotoCVPath(字符串fotoCVPath){
this.fotoCVPath=fotoCVPath;
}
}
在你我的页面中,我有这样的元素graphicImage:
public class UserPage {
private String fotoCVPath;
//all variabile
private String getRandomImageName() {
int i = (int) (Math.random() * 10000000);
return String.valueOf(i);
}
public void editImage() {
//init the fotoCVPath
fotoCVPath = fotoCVPath + "?tmpVal=" + getRandomImageName();
}
/**
* @return the fotoCVPath <br>
*
* @author - asghaier <br>
*
* Created on 29/mag/2014
*/
public String getFotoCVPath() {
return fotoCVPath;
}
/**
* @param fotoCVPath the fotoCVPath to set <br>
*
* @author- asghaier <br>
*
* Created on 29/mag/2014
*/
public void setFotoCVPath(String fotoCVPath) {
this.fotoCVPath = fotoCVPath;
}
}
<h:panelGrid ...al param >
<h:column>
<p:graphicImage id="imgCV" value="#{userPage.fotoCVPath}" styleClass="imgCVStyle" />
</h:column>
</h:panelGrid>
当我喜欢重新加载图像时,更新组件panelGrid
就我的例子来说,我有很多用处
<p:ajax event="click" onstart="PF('uploadImgCV').show();" update ="idPanelGrid"/>
在
我希望此模式能帮助您解决问题也许您应该在tomcat邮件列表中询问此问题
<h:panelGrid ...al param >
<h:column>
<p:graphicImage id="imgCV" value="#{userPage.fotoCVPath}" styleClass="imgCVStyle" />
</h:column>
</h:panelGrid>
<p:ajax event="click" onstart="PF('uploadImgCV').show();" update ="idPanelGrid"/>