FileDownload primefaces的组件在使用JasperReports生成报告时导致异常NullPointerException

时间:2013-08-22 22:17:57

标签: jsf-2 primefaces jasper-reports download

我有申请报告。当我在本地部署和运行时,它会生成报告并且下载完美,没有任何问题。 (在应用程序报告中创建文件并完成文件下载)

但是,当我在公司服务器上部署应用程序时,我尝试打印报告并发生NullPointterException异常。

这是堆栈跟踪:

Aug 21, 2013 5:26:01 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [FacesServlet] in context with path [/WebMap] threw exception [javax.servlet.ServletException] with root cause
java.lang.NullPointerException
    at org.primefaces.component.filedownload.FileDownloadActionListener.processAction(FileDownloadActionListener.java:53)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:84)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:773)
    at javax.faces.component.UICommand.broadcast(UICommand.java:296)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:310)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at web.web.filter.ConexaoHibernateFilter.doFilter(ConexaoHibernateFilter.java:31)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:344)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:110)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:98)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:95)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:120)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:55)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:36)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:150)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

此应用程序的代码部分如下:

下载页面

<?xml version="1.0" encoding="ISO-8859-1" ?>
    <!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.prime.com.tr/ui">

    <ui:composition template="/templates/interno.xhtml">
        <ui:define name="titulo">
            Módulo de Relatórios
        </ui:define>


        <ui:define name="corpo">

            <p:tabView id="tabView">
                <p:tab id="tab1" title="Download do relatorio das torres">
                    <div id="administracao_de_usuarios">

                        <h:form>
                            <span style="color: RGB(48, 122, 239);"> Para realizar o download do relatório, clique em uma das
                                opções de arquivo abaixo: </span>
                            <br />

                            <h:messages id="excecoes"
                                style="list-style-type: decimal; font-size: 14px; padding-left: 5px;"
                                title="Erros de preenchimento encontrados" />

                            <br />

                            <h:commandLink title="Relatório em PDF">
                                <f:setPropertyActionListener target="#{relatorioBean.tipoRelatorio}"
                                    value="1" />
                                <p:fileDownload value="#{relatorioBean.arquivoRetorno}" />
                                <h:graphicImage library="imagens" name="pdf.png" />
                                <span class="menu_link2">Arquivo PDF</span>
                            </h:commandLink>

                        </h:form>
                    </div>

                </p:tab>

            </p:tabView>


    </ui:define>
</ui:composition>
</html>

RelatorioBean

import java.util.HashMap;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import org.primefaces.model.StreamedContent;

import web.util.RelatorioUtil;
import web.util.UtilException;

@ManagedBean(name = "relatorioBean")
@RequestScoped
public class RelatorioBean {

    private StreamedContent arquivoRetorno;
    private int tipoRelatorio;

    public StreamedContent getArquivoRetorno() {
        FacesContext context = FacesContext.getCurrentInstance();
        String nomeRelatorioJasper = "relatorio";
        String nomeRelatorioSaida = "Relatório_torres_de_transmissão";      
        RelatorioUtil relatorioUtil = new RelatorioUtil();
        HashMap parametrosRelatorio = null;

        try {
            this.arquivoRetorno = relatorioUtil.geraRelatorio(
                    parametrosRelatorio, nomeRelatorioJasper,
                    nomeRelatorioSaida, this.tipoRelatorio);
        } catch (UtilException e) {
            context.addMessage(null, new FacesMessage(e.getMessage()));
            return null;
        }
        return this.arquivoRetorno;
    }

    public void setArquivoRetorno(StreamedContent arquivoRetorno) {
        this.arquivoRetorno = arquivoRetorno;
    }

    public int getTipoRelatorio() {
        return tipoRelatorio;
    }

    public void setTipoRelatorio(int tipoRelatorio) {
        this.tipoRelatorio = tipoRelatorio;
    }

}

RelatorioUtil

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;

import javax.faces.context.FacesContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.export.JRPdfExporter;

import net.sf.jasperreports.engine.util.JRLoader;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import web.util.UtilException;

public class RelatorioUtil {

    public static final int RELATORIO_PDF = 1;


    public StreamedContent geraRelatorio(HashMap parametrosRelatorio,
            String nomeRelatorioJasper, String nomeRelatorioSaida,
            int tipoRelatorio) throws UtilException {
        StreamedContent arquivoRetorno = null;

        try {
            FacesContext context = FacesContext.getCurrentInstance();
            Connection conexao = this.getConexao();
            String caminhoRelatorio = context.getExternalContext().getRealPath(
                    "relatorios");


            String caminhoArquivoJasper = caminhoRelatorio + File.separator
                    + "relatorioTorres" + ".jasper";

            String caminhoArquivoRelatorio = null;

            JasperReport relatorioJasper = (JasperReport) JRLoader
                    .loadObject(caminhoArquivoJasper);
            JasperPrint impressoraJasper = JasperFillManager.fillReport(
                    relatorioJasper, parametrosRelatorio, conexao);
            JRExporter tipoArquivoExportado = null;
            String extensaoArquivoExportado = "";
            File arquivoGerado = null;

            switch (tipoRelatorio) {
            case RelatorioUtil.RELATORIO_PDF:
                tipoArquivoExportado = new JRPdfExporter();
                extensaoArquivoExportado = "pdf";
                break;
            default:
                tipoArquivoExportado = new JRPdfExporter();
                extensaoArquivoExportado = "pdf";
                break;
            }
            caminhoArquivoRelatorio = caminhoRelatorio + File.separator
                    + nomeRelatorioSaida + "." + extensaoArquivoExportado;
            arquivoGerado = new java.io.File(caminhoArquivoRelatorio);
            tipoArquivoExportado.setParameter(JRExporterParameter.JASPER_PRINT,
                    impressoraJasper);
            tipoArquivoExportado.setParameter(JRExporterParameter.OUTPUT_FILE,
                    arquivoGerado);
            tipoArquivoExportado.exportReport();
            arquivoGerado.deleteOnExit();

            InputStream conteudoRelatorio = new FileInputStream(arquivoGerado);
            arquivoRetorno = new DefaultStreamedContent(conteudoRelatorio,
                    "application/" + extensaoArquivoExportado,
                    nomeRelatorioSaida + "." + extensaoArquivoExportado);
        } catch (JRException e) {
            throw new UtilException("Não foi possível gerar o relatório.", e);
        } catch (FileNotFoundException e) {
            throw new UtilException("Arquivo do relatório não encontrado.", e);
        }
        return arquivoRetorno;
    }

    private Connection getConexao() throws UtilException {
        java.sql.Connection conexao = null;
        try {
            Context initContext = new InitialContext();
            Context envContext = (Context) initContext
                    .lookup("java:/comp/env/");
            javax.sql.DataSource ds = (javax.sql.DataSource) envContext
                    .lookup("jdbc/WebConection");
            conexao = (java.sql.Connection) ds.getConnection();
        } catch (NamingException e) {
            throw new UtilException(
                    "Não foi possível encontrar o nome da conexão do banco.", e);
        } catch (SQLException e) {
            throw new UtilException("Ocorreu um erro de SQL.", e);
        }
        return conexao;
    }
}

有人可以帮我解决这个错误吗?为什么本地生成文件并执行下载,但服务器上会出现此问题?

2 个答案:

答案 0 :(得分:0)

根据PrimeFaces 2.1 source codeFileDownloadActionListener第53行的NPE表明#{relatorioBean.arquivoRetorno}实际返回null。让我们看一下:

} catch (UtilException e) {
    context.addMessage(null, new FacesMessage(e.getMessage()));
    return null;
}

看起来,当null被抛出时,它会返回UtilException。在文件下载请求中添加面部消息完全没有意义。它不会出现在任何地方。您最好打印/记录堆栈跟踪

} catch (UtilException e) {
    e.printStackTrace();
    return null;
}

或者更好的是,只需删除整个try-catch并直接抛出该异常。

public StreamedContent getArquivoRetorno() throws UtilException {
    // ...
}

这样您就会面对真正的异常,而不是隐藏真正问题的NullPointerException

答案 1 :(得分:0)

经过很长一段时间没有看到stackoverflow,我意识到我需要解决这个问题,这个问题很久以前就已经发生了。所以这就是:

在这种情况下,我根据数据库表结构制作了报表模板,该结构具有命名模式。

当我将代码带到服务器时,有一个数据库表结构,它有不同的命名模式。

通过这种方式,报告未生成且无法下载,从而生成NullPointerException。

在注意到服务器的数据库表结构发生了微小的变化之后,我不得不使用iReport Designer重新编写报表模板,基于新的表结构,该结构遵循与前一个表结构不同的命名模式。 / p>

因此,当我根据新结构重构模板时,JasperReports的报告生成完美无缺。