2

Tapestry 5.1.0.5 フレームワークを使用して Java で記述された Web アプリケーションに取り組んでいます。このフレームワークには、すぐに使用できる JasperReports のサポートがないため、ChenilleKit の JasperReport サービスを変更するサービスを作成しました。私は ChenilleKit のバージョンには依存せず、代わりに JasperReport 3.5.0 依存関係を使用します。これは必要な情報ではないかもしれませんが、具体的に言っても問題はありません。

とにかく、私のサービスはかなりうまくいっています。Web アプリケーションに組み込み、基本的なレポートを PDF、XLS、HTML、および CSV 形式でコンパイルおよび出力できます。ただし、jasperReport XML ファイルで SQL を取得してパラメータ マップを適切にロードすることに大きな問題があります。

startdate および enddate パラメーターを使用してレポートを実行しようとすると、次のエラーが発生します。

SQLException: Missing IN or OUT parameter at index:: 1

SQLの知識は、これは、SQLに渡されていない何らかの形式のパラメーターがあることを意味すると言うでしょう。デバッグ ステートメントは、パラメーターを問題なく渡しており、少なくとも一部が XML レポートに反映されていることを示しています。

たとえば、Title、StartDate、および EndDate という 3 つのパラメーターをレポートに渡しているとします。タイトルはレポートのレンダリングに表示されますが、StartDate と EndDate は翻訳で失われているように見えますか?

私の会社の JSP-Tomcat-Servlet ベースのアプリケーションで JasperReports を使用してもほぼ同じコードが機能するため、何が欠けているのかわかりません。

とにかく、コードを示し、何が起こっているかを説明し始めます。

public StreamResponse getReport(String reportTitle, ExportFormat formMode, Date startDate, Date endDate) {
    Map<String,String> parameterMap = loadParameters(reportTitle);
    Connection conn = null;
    OutputStream os = new ByteArrayOutputStream();

    try{
        conn = Report.getConnection();

        Resource resc = new ContextResource(cimpl, "src/main/webapp/reports/"+reportTitle+".xml");

        log.debug("Calling fillAndExport to fetch the report " + reportTitle);
        log.debug("resource="+resc+"\n"+"formMode="+formMode+"\n"+"parameterMap="+parameterMap+"\n"+"conn="+conn+"\n"+
                "outputStream="+os);

        SimpleDateFormat repDate = new SimpleDateFormat("MM/dd/yyyy HH:mm");
        parameterMap.put("StartDate", repDate.format(startDate));
        parameterMap.put("EndDate", repDate.format(endDate));

        log.debug("StartDate into report: " + parameterMap.get("StartDate"));
        log.debug("EndDate into report: " + parameterMap.get("EndDate"));

        js.fillAndExport(resc, formMode, parameterMap, conn, os);
        SimpleDateFormat sdf = new SimpleDateFormat("MMMddyyyy");

        return new JasperStreamResponse((ByteArrayOutputStream) os, formMode, reportTitle+"-"+sdf.format(startDate)+"-"
                +sdf.format(endDate));
    }catch (Exception e){
        log.error("Caught exception while trying to execute the report fillAndExport service method.");
        throw new TapestryException("Issue executing report", e);
    } finally {
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                System.out.println("Could not close the JDBC connection!!");
            }
        }
    }
}

簡単に言うと、レポート リソースを読み込み、StartDate パラメーターと EndDate パラメーターを追加します (Title は既に parameterMap にあります)。次に、fillAndExport を使用してレポートを生成する JasperService を呼び出します。例外がない場合は、ストリームでブラウザに返されます。

例外が発生した特定の時間のデバッグステートメントを次に示します。

[DEBUG] AppModule.ReportService Loaded report class: com.moremagic.reports.TriggerReport
[DEBUG] AppModule.ReportService Calling fillAndExport to fetch the report Trigger
[DEBUG] AppModule.ReportService resource=context:src/main/webapp/reports/Trigger.xml
formMode=HTML
parameterMap={Title=Triggering Merchant Commission}
conn=oracle.jdbc.driver.T4CConnection@7c974e4b
outputStream=
[DEBUG] AppModule.ReportService StartDate into report: 08/22/2010 14:19
[DEBUG] AppModule.ReportService EndDate into report: 08/23/2010 14:19
[DEBUG] AppModule.JasperService Constructed configuration: {}
[DEBUG] AppModule.JasperService Invoking method com.moremagic.services.AppModule.buildJasperService(Logger, Map) (at AppModule.java:188).
[DEBUG] AppModule.JasperService Using template -> src/main/webapp/reports/Trigger.xml
[DEBUG] AppModule.JasperService In fillReport, parameterMap is : {EndDate=08/23/2010 14:31, StartDate=08/22/2010 14:31, Title=Triggering Merchant Commission}

[ERROR] AppModule.JasperService Caught exception in fillReport of ReportsServiceImpl {}
net.sf.jasperreports.engine.JRException: Error executing SQL statement for : WebappReport1
Caused by: java.sql.SQLException: Missing IN or OUT parameter at index:: 1

ご覧のとおり、値は JasperService が JapserReports API を呼び出すまでずっとパラメータ マップにあります。次に、JasperService のコードとレポートの一部を示して、SQL が壊れていることを確認できるようにします。

ジャスパーサービス:

/**
 * Fills the report design loaded from the supplied input resource and returns the generated report object.
 * <p/>
 * if parameter <em>jasperPrint<em> not null, the data filled into <em>jasperPrint</em>
 * instead of returns a new jasper print object.
 *
 * @param jasperPrint
 * @param inputResource the input resource (report template file ".jrxml")
 * @param parameterMap  the parameter map
 * @param dataSource    the datasource, either a JRDataSource or an SQL JDBC Connection.
 *
 * @return
 */
public JasperPrint fillReport(JasperPrint jasperPrint, Resource inputResource, Map parameterMap, Object dataSource) throws JRException
{
    JasperReport jasperReport = doCompileReportSource(inputResource);
    JasperPrint actualJasperPrint;

    logger.debug("In fillReport, parameterMap is : " + parameterMap + "\n startDate: " + parameterMap.get("StartDate") + "\n endDate: " + parameterMap.get("EndDate"));

    try
    {
        if (dataSource != null && dataSource instanceof JRDataSource)
            actualJasperPrint = JasperFillManager.fillReport(jasperReport, parameterMap, (JRDataSource) dataSource);
        else if(dataSource != null && dataSource instanceof Connection)
            actualJasperPrint = JasperFillManager.fillReport(jasperReport, parameterMap, (Connection) dataSource);
        else
            actualJasperPrint = JasperFillManager.fillReport(jasperReport, parameterMap);

        if (jasperPrint != null)
        {
            for (Object page : actualJasperPrint.getPages())
                jasperPrint.addPage((JRPrintPage) page);
        }
        else
            jasperPrint = actualJasperPrint;

        return jasperPrint;
    }
    catch (JRException e)
    {
        logger.error("Caught exception in fillReport of ReportsServiceImpl {}", e);
        throw new JRException(e);
    }
}

報告:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" 
 "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport 
    name="WebappReport1" 
    pageWidth="595" 
    pageHeight="842" 
    columnWidth="555" 
    columnSpacing="0" 
    leftMargin="20" 
    rightMargin="20" 
    topMargin="30" 
    whenNoDataType="AllSectionsNoDetail"
    bottomMargin="30"> 
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="9" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="9" isBold="true" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="9" isItalic="true" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
<parameter name="Title" class="java.lang.String"/>
<parameter name="StartDate" class="java.lang.String" />
<parameter name="EndDate" class="java.lang.String" />


<!--This is report query string used to fill data-->
<queryString><![CDATA[
SELECT 
something
from table b
    where
b.ba_timestamp between to_date( $P!{StartDate}, 'MM/DD/YYYY HH24:MI' ) and to_date( $P!{EndDate}, 'MM/DD/YYYY HH24:MI' )+1 
]]></queryString>
4

1 に答える 1

6

! を削除する必要があると思います。SQL クエリで使用するか、パラメーターを引用符で囲みます。

jasper クエリでは、$P{xyz} はパラメーターを作成してバインドしますが、$P!{xyz} はクエリ文字列を変更します。あなたの場合、生の(引用符で囲まれていない)パラメーターを追加して無効なクエリを作成していると思います。

詳細については、このブログ投稿をご覧ください

于 2010-08-23T20:44:20.180 に答える