我有以下内容:
<p:dataTable id="photoPreview" var="file" value="#{ fileUploadMB.filesList }">
<p:column>
<p:commandLink ajax="false">
<p:graphicImage value="#{ fileUploadMB.streamedContentFromFile }" rendered="#{ file.fileIsImage }">
<f:param name="N" value="#{ file.N() }" />
<f:param name="size" value="thumbnail" />
</p:graphicImage>
<p:fileDownload value="#{ fileUploadMB.streamedContentFromFile }"/>
<f:param name="N" value="#{ file.N() }" />
</p:commandLink>
</p:column>
<p:column>
<p:commandLink value="Remove" disabled="#{ loginMB.customerRole and !orderDetailMB.fileModificationPermitted }" action="#{ fileUploadMB.removeUploadedFile }" rendered="#{ file.uploadedFilePresent }" update="photoPreview">
<f:param name="N" value="#{ file.N() }" />
</p:commandLink>
</p:column>
</p:dataTable>
但是当我点击Remove链接时,dataTable不会更新。我知道正在调用fileUploadMB.removeUploadedFile()。我知道file.isFileIsImage()之后被调用。但是浏览器没有任何变化。 Firebug的Net选项卡向我显示响应中没有任何用处,但这可能不可靠;当您查看响应子选项卡时,Firebug会重新获取URL。
FileUploadMB的相关代码:
@ManagedBean
@SessionScoped
public class FileUploadMB implements Serializable {
private static final Logger logger = LoggerFactory.getLogger(Thread.currentThread().getStackTrace()[1].getClassName());
private Map<Integer, OrderCustomerFile> uploadedFilesList;
private List<OrderCustomerFile> uploadedFilesToDelete;
private static final int MAX_NUMBER_OF_FILES = 5;
private List<FileN> filesList;
// ----------------------------------------------------
public boolean fileIsImage(int rowIndex) {
if( rowIndex == 0 ) {
logger.debug( "rowIndex={}", rowIndex );
logger.debug( "uploadedFileList={}", uploadedFilesList );
logger.debug( "uploadedFileList.keys={}", uploadedFilesList.keySet() );
}
if( !uploadedFilesList.containsKey(rowIndex) ) {
if( rowIndex == 0 )
logger.debug( "nope" );
return false;
}
String ct = uploadedFilesList.get(rowIndex).getContentType();
if (ct.contains("gif") || ct.contains("jpeg") || ct.contains("png") || ct.contains("jpe"))
return true;
else
return false;
}
// ----------------------------------------------------
public void removeUploadedFile() {
FacesContext context = FacesContext.getCurrentInstance();
logger.debug( "context={}", context );
String N = context.getExternalContext().getRequestParameterMap().get("N");
logger.debug( "N={}", N );
removeUploadedFile( Integer.valueOf( N ) );
}
// ----------------------------------------------------
public void removeUploadedFile(int rowIndex) {
logger.debug( "uploadedFileList={}", uploadedFilesList );
logger.debug( "uploadedFileList.keys={}", uploadedFilesList.keySet() );
logger.debug( "rowIndex={}", rowIndex );
if( uploadedFilesList.get(rowIndex).getUploadedFile() == null ) {
logger.debug( "Wants to delete {}", uploadedFilesList.get(rowIndex).getFilePath() );
uploadedFilesToDelete.add( uploadedFilesList.get(rowIndex) );
}
uploadedFilesList.remove( rowIndex );
logger.debug( "uploadedFileList={}", uploadedFilesList );
logger.debug( "uploadedFileList.keys={}", uploadedFilesList.keySet() );
}
// ----------------------------------------------------
public List<FileN> getFilesList() {
if( filesList == null )
buildFilesList();
//logger.debug( "filesList={}", filesList );
return filesList;
}
public void buildFilesList() {
Map<String,Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
filesList = new ArrayList<FileN> ();
for( int q=0; q<MAX_NUMBER_OF_FILES; q++ ) {
FileN file = new FileN (this, q);
filesList.add( file );
logger.debug( "file={} hashCode={}", file, file.hashCode() );
viewMap.put( String.valueOf( file.hashCode() ), file );
}
}
// ----------------------------------------------------
public StreamedContent getStreamedContentFromFile() {
// See http://stackoverflow.com/questions/8207325/display-image-from-database-with-pgraphicimage/12452144#12452144
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
logger.debug( "RENDER_RESPONSE phase" );
// So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
String N = context.getExternalContext().getRequestParameterMap().get("N");
String size = context.getExternalContext().getRequestParameterMap().get("size");
logger.debug( "N={}, size={}", N, size );
return streamedContentFromFile( Integer.valueOf( N ), size );
}
// ----------------------------------------------------
public StreamedContent streamedContentFromFile( int rowIndex ) {
return streamedContentFromFile( rowIndex, "normal" );
}
// ----------------------------------------------------
public StreamedContent streamedContentFromFile( int rowIndex, String size ) {
logger.debug( "rowIndex={}", rowIndex );
//fichier provenant de la BD (ayant deja ete sauvegarde)
if (uploadedFilesList.get(rowIndex).getFilePath() != null) {
OrderCustomerFile iof = uploadedFilesList.get( rowIndex );
try {
java.io.File file = new java.io.File( iof.getFilePath() );
if (file.exists()) {
logger.debug( "Streaming file {} ct={}", iof.getFilePath(), iof.getContentType() );
BufferedInputStream bif = new BufferedInputStream(
new FileInputStream(
new java.io.File(iof.getFilePath())));
logger.debug( "bif={}", bif );
String name = iof.getFilenameOriginal();
if( name == null )
name = iof.getFilePath().substring(iof.getFilePath().lastIndexOf("/")+1);
logger.debug( "name={}", name );
return new DefaultStreamedContent(bif, iof.getContentType(), name );
}
}
catch (FileNotFoundException e ) {
logger.error( null, e );
MessagesMB.showErrorMessage(MessagesMB.ORDER_DETAILS_FILE_NOT_FOUND);
}
//fichier n'ayant pas encore ete sauvegarde dans la BD
}
else if (null != uploadedFilesList.get(rowIndex).getUploadedFile()) {
try {
OrderCustomerFile file = uploadedFilesList.get(rowIndex);
return new DefaultStreamedContent( file.getUploadedFile().getInputstream(),
file.getContentType(),
file.getFilenameOriginal()
);
}
catch (IOException e ) {
logger.error( null, e );
MessagesMB.showErrorMessage(MessagesMB.ERROR_GENERAL);
}
}
return null;
}
// ----------------------------------------------------
public boolean uploadedFilePresent(int rowIndex) {
return uploadedFilesList.containsKey(rowIndex); // && !hasBeenPersisted( rowIndex );
}
}
FileN的相关部分:
@ManagedBean
@ViewScoped
public class FileN implements Serializable {
private static final Logger logger =
LoggerFactory.getLogger(Thread.currentThread().getStackTrace()[1].getClassName());
private Integer N;
private FileUploadMB fileUploadMB;
// ----------------------------------------------------
/** Creates a new instance of File */
public FileN( FileUploadMB fileUploadMB, Integer N ) {
this.N = N;
this.fileUploadMB = fileUploadMB;
logger.debug( "N={}", N );
}
// ----------------------------------------------------
public int N () {
return N.intValue();
}
// ----------------------------------------------------
public String getN () {
return N.toString();
}
// ----------------------------------------------------
public boolean isFileIsImage () {
if( N.equals( 0 ) ) logger.debug( "N={}", N );
return fileUploadMB.fileIsImage( N.intValue() );
}
// ----------------------------------------------------
public boolean isUploadedFilePresent () {
return fileUploadMB.uploadedFilePresent( N );
}
}
(是的,我可能还有很多其他问题,FileN并不是View-scoped Bean。)
使用JSF-2.1,Primefaces-3.0,Glassfish-3.1.2.2,jdk-1.7.0
Firebug Net响应是:
<?xml version='1.0' encoding='UTF-8'?>
<partial-response><changes><update id="j_idt86"><![CDATA[<div id="j_idt86" class="ui-messages ui-widget"></div>]]></update><update id="javax.faces.ViewState"><![CDATA[3615293429385705722:7636138965730106845]]></update></changes></partial-response>
HttpFox给了我同样的东西:
<partial-response>
<changes>
<update id="j_idt86">
<div id="j_idt86" class="ui-messages ui-widget"></div>
</update>
<update id="javax.faces.ViewState">-2752869461800547313:-2875920138022122822</update>
</changes>
</partial-response>
这超过了https,因此获取tcpdump会更难。
答案 0 :(得分:1)
使用Primefaces-3.0
<p:dataTable>
在较早的PF 3.x版本中有一个错误导致<p:dataTable>
无法通过<p:dataTable>
本身内部的命令进行ajax更新。 / p>
您有两个选择:
升级至at least PrimeFaces 3.4。
Ajax-更新父组件。也许是@form
?
备选方案是按ajax="false"
关闭ajax。