p:dataTable和p:commandLink无法正常工作

时间:2013-07-25 17:00:17

标签: jsf-2 primefaces

我有以下内容:

<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会更难。

1 个答案:

答案 0 :(得分:1)

  

使用Primefaces-3.0

<p:dataTable>在较早的PF 3.x版本中有一个错误导致<p:dataTable>无法通过<p:dataTable>本身内部的命令进行ajax更新。 / p>

您有两个选择:

  1. 升级至at least PrimeFaces 3.4。

  2. Ajax-更新父组件。也许是@form

  3. 备选方案是按ajax="false"关闭ajax。