【问题标题】:PrimeFaces fileDownload method not called?PrimeFaces fileDownload 方法没有被调用?
【发布时间】:2019-01-30 23:24:02
【问题描述】:

我有多个页面允许下载相同的资源(从我的数据库中检索)。

问题是下载只对其中一些有效,即使使用相同的代码并调用相同的 bean。

这件事变得很烦人,因为在非工作页面上,单击下载链接只会重新加载页面而没有任何消息/异常,所以我无法找出发生了什么。

这是我的 BEAN 代码:

package ManagedBeans;

import ejb.DispensaManagerLocal;
import entity.Dispensa;
import entity.Utente;
import java.io.ByteArrayInputStream;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.RateEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

/**
 *
 * @author stefano
 */
@ManagedBean
@RequestScoped
public class DispensaBean {

    @EJB
    private DispensaManagerLocal dispensaManager;
    @ManagedProperty(value = "#{loginBean.utente}")
    private Utente utente;

    public Utente getUtente() {
        return utente;
    }

    public void setUtente(Utente utente) {
        this.utente = utente;
    }

    /**
     * Creates a new instance of DispensaBean
     */
    public DispensaBean() {
    }

    public StreamedContent getDownload() {
        String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("dispensaId");        
        System.out.println("________" + id);
        Dispensa d = dispensaManager.findById(Integer.parseInt(id));        
        String type = getMimeFromByte(d.getDatiFile());
        String estensione = "";
        if(type.equals("application/pdf")){
            estensione = ".pdf";
        } else if(type.equals("application/zip")) {
            estensione = ".zip";
        } else if(type.equals("application/vnd.ms-powerpoint")) {
            estensione = ".ppt";
        }        
        return new DefaultStreamedContent(new ByteArrayInputStream(d.getDatiFile()), type, d.getTitolo() + estensione);
    }


    private String getMimeFromByte(byte[] src) {
        if (src[0] == 0x25 && src[1] == 0x50 && src[2] == 0x44 && src[3] == 0x46) {
            return "application/pdf";
        }
        if (src[0] == 0x50 && src[1] == 0x4b) {
            return "application/zip";
        }
        if (src[0] == 0xd0 && src[1] == 0xcf && src[2] == 0x11 && src[3] == 0xe0 && src[4] == 0xa1 && src[5] == 0xb1 && src[6] == 0x1a && src[7] == 0xe1) {
            return "application/vnd.ms-powerpoint";
        }
        return "application/octet-stream";
    }

}

现在,在非工作页面上,getDownload() 方法未被调用,因为它不打印任何内容。

这是下载按钮代码

<h:form style="float: right">
    <pou:commandLink id="downloadDispensa" ajax="false" disabled="#{!loginBean.logged}">
       <pou:graphicImage value="./resources/images/download.png" height="30"/>
       <pou:fileDownload value="#{dispensaBean.getDownload()}"/>                                                    
       <f:param name="dispensaId" value="#{dispensa.id}"/>
    </pou:commandLink>                                
</h:form> 

我注意到下载链接只是重新加载页面而不是调用方法,并且这只发生在#{dispensa.id} 依赖于 GET 参数的页面中。

例如,我有一个名为 dispensa.xhtml 的页面,如果没有传递 GET 参数,它会显示我在数据库中的所有文件。

确实,dispensa.xhtml?id=5 将只显示 id=5 的文件。

在第一种情况下,单击下载链接可以正常工作。 在第二种情况下执行此操作将重新加载页面并丢失 GET 参数,因此它将加载 dispensa.xhtml 而不是 dispensa.xhtml?id=5

我认为使用 GET 参数存在一些问题,但是..昨天它工作了,我没有更改此代码!

另一个非工作页面是ricerca.xhtml,它显示了ricerca.xhtml?key=query 给出的查询的(多个)结果。

最后,搞砸了,在profile.xhtml?user=username WORKS 中下载。

这破坏了我关于 GET 参数的整个理论。

为避免byte[] datiFile 为空,我以这种方式编辑了我的Dispensa 实体:

@Basic(optional = true, fetch=FetchType.EAGER)
@Lob
@Column(name = "datiFile")    
private byte[] datiFile;

我不知道该怎么做,因为它没有说明出了什么问题,它只是重新加载页面,绕过我的下载!

编辑:

我尝试更改我的getDownload() 方法以返回我的HD 上的File,以了解问题是否是由数据库上的空数据引起的,但它仍然无法正常工作!

【问题讨论】:

  • 您应该将解决方案作为答案发布,而不是在问题中(并且不要将 SOLVED 放在标题中,而只是将其标记为已接受)。 Stack Overflow 是一个问答网站,而不是论坛。
  • 从没想过我能接受自己的答案!
  • 你只是没有得到积分:)

标签: jsf primefaces bytearray download


【解决方案1】:

似乎我通过使用替代解决方案解决了这个问题。

我都改了

<h:form style="float: right">
        <pou:commandLink id="downloadDispensa" ajax="false" disabled="#{!loginBean.logged}">
           <pou:graphicImage value="./resources/images/download.png" height="30"/>
           <pou:fileDownload value="#{dispensaBean.getDownload()}"/>                                                    
           <f:param name="dispensaId" value="#{dispensa.id}"/>
        </pou:commandLink>                                
    </h:form> 

<h:form style="float: right">
    <h:outputLink id="downloadDispensa" disabled="#{!loginBean.logged}" target="_blank" value="./download.xhtml?id=#{dispensa.id}">
         <pou:graphicImage value="./resources/images/download.png" height="30"/>                                    
     </h:outputLink>                                
</h:form>

download.xhtml 有这个代码:

<script type="text/javascript">
    if(document.referrer == "" || document.referrer == "download.xhtml"){
        self.location='./index.xhtml';
    }
    document.onblur = new Function('self.close()');
</script>
<h:body onload="document.getElementsByClassName('downloadDispensa')[0].click();" rendered="#{loginBean.logged}">
    <h:form>            
        <h:commandLink class="downloadDispensa" id="downloadDispensa" style="display: none">                
            <pou:graphicImage value="./resources/images/download.png" height="30"/>
            <pou:fileDownload value="#{dispensaBean.download}"/>                                                                                       
            <f:param name="dispensaId" value="#{request.getParameter('id')}"/>
        </h:commandLink> 
    </h:form>        
</h:body>
<h:body onload="self.location='./index.xhtml';" rendered="#{!loginBean.logged}">
</h:body>

所以它会加载下载页面,自动点击下载链接,并在显示下载对话框时自动关闭页面。

【讨论】:

    【解决方案2】:

    我也遇到过同样的问题。我已经对其进行了调试,并知道表单中有表单,因为我在另一个模板中包含了模板,因为它是一个摘要屏幕。所以我删除了内部模板中的所有 h:form 标签,除了根 xhtml 页面这些模板和它的工作。

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 2016-06-14
      • 1970-01-01
      • 2012-03-13
      • 2014-06-02
      • 2011-08-28
      • 2017-02-24
      相关资源
      最近更新 更多