java - Primefaces 消息也不适用于流文件

标签 java eclipse jsf-2 primefaces xhtml

当我尝试在代码中使用 primefaces 消息时遇到问题。当我刚刚进行测试时,消息运行良好,但是当我执行流文件并尝试在 xhtml 中发送消息时,该过程运行良好,但消息没有增长。

我的代码:

public void cadastrar () throws KeyStoreException, CADoesntExistsException,        NoSuchAlgorithmException, CertificateException, IOException      
{           
    FacesContext fc = FacesContext.getCurrentInstance();            
    if((controlador.checkUserIfExist(certificadoModel.getUsername()) == false) || (controlador.checkUserIfExist(certificadoModel.getUsername()) == true && authorization == true))
    {
        System.out.println("Revoke: " + authorization);
        System.out.println("Check: " + controlador.checkUserIfExist(certificadoModel.getUsername()));
        //KeyStore keyStore = controlador.cadastrar(certificadoModel);      
        System.out.println("Bean Class: " + certificadoModel.getMensagem());
        /*       
        ExternalContext ec = fc.getExternalContext();

        ec.responseReset(); 
        ec.setResponseContentType("application/x-pkcs12"); 
        //ec.setResponseContentLength(contentLength); 
        ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + certificadoModel.getUsername() + ".p12" + "\""); 

        OutputStream output = ec.getResponseOutputStream();
        keyStore.store(output, certificadoModel.getPassword().toCharArray());
          */
        fc.addMessage("mensagem", new FacesMessage(FacesMessage.SEVERITY_INFO, "Teste", "")); 
        //fc.responseComplete();            
        controlador.clean(certificadoModel);            
    }else           
        fc.addMessage("mensagem", new     FacesMessage(FacesMessage.SEVERITY_ERROR, "Um usuário com o mesmo username já está     cadastrado!", ""));  
        controlador.clean(certificadoModel);
}

我的页面代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"> 
    <ui:decorate template="/resources/template/default.xhtml">
        <ui:define name="centro"> 
            <h:form id="cadastro"> 
                <p:panel id="painelCadastro" header="Novo Cadastro" style="margin-bottom:10px;">         
                    <p:messages id="mensagem" autoUpdate="true" closable="true" />   

                    <p:commandButton action="#{certificadoBean.cadastrar}"  ajax="false" value="Cadastrar" update="mensagem" />                   
                    <p:commandButton outcome="homePage" ajax="false" value="Home Page"/>                                  
                </p:panel>       
            </h:form>  
        </ui:define>
    </ui:decorate>
</html>
<小时/>

@BalusC,这就是我所做的。

xhtml

                <p:commandButton value="Cadastrar" action="#{downloadBean.prepareDownload}" update="mensagem" />
                <p:messages globalOnly="true" />
                <h:outputScript rendered="#{not empty downloadBean.downloadKey}">
                    window.location = '#{request.contextPath}/download?key=#{downloadBean.downloadKey}';
                </h:outputScript>   

                <p:commandButton outcome="homePage" ajax="false" value="Home Page"/>                                  
            </p:panel>       
        </h:form>  

DownloadBean类

public class DownloadBean {

private String downloadKey; 

public void prepareDownload() throws NamingException {
    FacesContext context = FacesContext.getCurrentInstance();

    CertificadoModel certificadoModel = new CertificadoModel();
    CertificadoControlador controlador = new CertificadoControlador();      

    if ((controlador.checkUserIfExist(certificadoModel.getUsername()) == false)) 
    {
        downloadKey = UUID.randomUUID().toString();     
        context.getExternalContext().getSessionMap().put(downloadKey, certificadoModel);
        context.addMessage("mensagem", new FacesMessage(FacesMessage.SEVERITY_INFO, "Usuário cadastrado com sucesso!", "")); 
    }else {
        context.addMessage("mensagem", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Um usuário com o mesmo username já está cadastrado!", ""));  
    }           
}

public String getDownloadKey() {
    return downloadKey;
}

下载Servlet类

public class DownloadServlet extends HttpServlet {

/****/
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    String downloadKey = request.getParameter("key");
    CertificadoModel certificadoModel = (CertificadoModel) request.getSession().getAttribute(downloadKey);

    System.out.println("Teste!");

    CertificadoControlador controlador = null;
    try {
        controlador = new CertificadoControlador();
    } catch (NamingException e) {
        e.printStackTrace();
    }
    request.getSession().removeAttribute(downloadKey);

    KeyStore keyStore = null;
    try {
        keyStore = controlador.cadastrar(certificadoModel);
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (CADoesntExistsException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }  

    response.reset();
    response.setContentType("application/x-pkcs12"); 
    //response.setContentLength(contentLength); 
    response.setHeader("Content-Disposition", "attachment; filename=\"" + certificadoModel.getUsername() + ".p12" + "\""); 

    try {
        keyStore.store(response.getOutputStream(), certificadoModel.getPassword().toCharArray());
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (IOException e) {           
        e.printStackTrace();
    }
}

在 web.xml 中

<servlet>
    <servlet-name>DownloadServlet</servlet-name>
    <servlet-class>br.com.certificado.beans.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>DownloadServlet</servlet-name>
    <url-pattern>/download</url-pattern>
</servlet-mapping>

最佳答案

您基本上是在尝试向 1 个 HTTP 请求返回 2 个 HTTP 响应。这根本不可能。

最好的办法是有条件地在 URL 上渲染 JavaScript window.location 调用,该调用会发送一个新的 HTTP 请求,返回所需的文件下载。简单的 servlet 是完成这项工作的一个非常好的工具。您可以使用此答案中列出的方法之一访问 servlet 中的托管 bean:Get JSF managed bean by name in any Servlet related class或者您可以只生成一个唯一的 session 属性 key 并将其作为请求参数传递。

这是使用最后一种方法的启动示例:

<h:form>
    ...
    <p:commandButton ... action="#{bean.prepareDownload}" update="@form" />
    <p:messages globalOnly="true" />
    <h:outputScript rendered="#{not empty bean.downloadKey}">
        window.location = '#{request.contextPath}/download?key=#{bean.downloadKey}';
    </h:outputScript>
</h:form>

(注意:/download 必须与 servlet 的 URL 模式完全匹配)

用这个bean:

private String downloadKey; // +Getter.

public void prepareDownload() {
    FacesContext context = FacesContext.getCurrentInstance();

    if (canDownload) {
        downloadKey = UUID.randomUUID.toString();
        context.getExternalContext().getSessionMap().put(downloadKey, certificadoModel);
        context.addMessage(null, infoMessage);
    } else {
        context.addMessage(null, errorMessage);
    }
}

以及这个 servlet:

@WebServlet("/download")
public class DownloadServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String downloadKey = request.getParameter("key");
        CertificadoModel certificadoModel = (CertificadoModel) request.getSession().getAttribute(downloadKey);
        request.getSession().removeAttribute(downloadKey);

        // ...

        response.reset();
        response.setContentType("application/x-pkcs12"); 
        response.setContentLength(contentLength); 
        response.setHeader("Content-Disposition", "attachment; filename=\"" + certificadoModel.getUsername() + ".p12" + "\""); 
        keyStore.store(response.getOutputStream(), certificadoModel.getPassword().toCharArray());
    }

}

关于java - Primefaces 消息也不适用于流文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15885497/

相关文章:

jsf-2 - 是否可以将全局过滤器放在 p :dataTable? 之外

redirect - JSF - 从 @PostConstruct 重定向后保留 Faces 消息

java - 使用迭代器遍历 HashMap 列表

java - jdbi 抛出 SQLException : Unknown system variable 'tx_read_only'

java - jar 内的类未被识别

JSF2 复合组件 : are #{cc. childCount} 和 <composite :insertChildren/> mutually exclusive?

java - hibernate nativesqlquery批量插入

java - 如何在pom中引用第三方jar来创建 super jar

java - 如何获取构建项目时使用的 eclipse 版本

java - 使用 GitHub 通过 Jenkins 将 EAR 部署到 WAS8.5 时出现 IncompatibleClassChangeError