2010-08-23 4 views
2

Tapestry 5.1.0.5 프레임 워크를 사용하여 Java로 작성된 웹 응용 프로그램에서 작업하고 있습니다. 이 프레임 워크에는 JasperReports에 대한 기본 지원이 없으므로 ChenilleKit의 JasperReport 서비스를 수정하는 서비스를 작성했습니다. 나는 ChenilleKit 버전에 의존하지 않고 대신 JasperReport 3.5.0 의존성을 사용합니다. 이것은 필요한 정보가 아닐 수도 있지만, 결코 구체적이지는 않습니다.JasperReports가 매개 변수를 제대로 읽지 못합니까?

어쨌든, 제 서비스는 꽤 잘 작동합니다. PDF 파일, XLS, HTML 및 CSV 형식으로 기본 보고서를 컴파일하고 출력 할 수 있습니다. 그러나 jasperReport XML 파일에서 SQL을 가져 와서 매개 변수 맵을 올바르게로드하는 것이 큰 문제입니다.

startdate 및 enddate 매개 변수를 사용하여 보고서를 실행하려고하면 다음 오류가 발생합니다.

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

SQL 지식이란 SQL에 전달되지 않는 매개 변수 형식이 있다는 뜻입니다. 디버그 문은 필자에게 매개 변수를 전달하고 있으며 일부는 XML 보고서를 작성하고 있음을 나타냅니다.

예를 들어 보고서에 Title, StartDate 및 EndDate 매개 변수 세 개를 전달합니다. 제목은 보고서 렌더링시 표시되지만 StartDate 및 EndDate는 번역에서 손실되는 것 같습니다.

거의 동일한 코드가 JasperReports를 사용하는 회사의 JSP-Tomcat-Servlet 기반 응용 프로그램에서 작동하기 때문에 내가 무엇을 놓치고 있는지 잘 모르겠습니다.

어쨌든 내가 코드를 보여주고 무슨 일이 일어나고 있는지 설명 시작합니다 :

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 및 종료 날짜 매개 변수를 (제목이 된 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} 
[email protected] 
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 중단 문제를 볼 수 있습니다.

JasperService :

/** 
* 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> 
+0

글쎄, 문제는 최저 수준입니다. 매개 변수가 설정되지 않습니다. 디버거로 Jasper로 뛰어 들어야합니다. 그런데 왜 날짜를 문자열로 포맷 한 다음 다시 파싱합니까? – Henning

+0

PrepareStatement를 사용하여 똑같은 연결을 사용하고 $ P! {StartDate}를 (를) 대체 한 동일한 정확한 SQL을 사용하여 정상적으로 실행됩니까? 서식을 준수해야합니다. 매개 변수는 매개 변수 MapMash HashMap에서도로드됩니다. Perplexing ... – Rich

+0

보고서 XML을 작성하지 않았기 때문에 주로 날짜 형식을 지정 했으므로 여기에 오기 전에 회사에서 수행 한 작업 방식입니다. 리팩토링하는 것은 나에게 가치가 없다. – Rich

답변

6

나는 당신이를 제거해야 하나 생각! SQL 쿼리에서 또는 매개 변수를 따옴표로 묶습니다.

재스퍼 쿼리에서 $ P {xyz}는 매개 변수를 만들고 바인딩하지만 $ P! {xyz}는 쿼리 문자열을 수정합니다. 귀하의 경우 원시 (인용되지 않은) 매개 변수를 추가하여 유효하지 않은 쿼리를 작성한다고 생각합니다.

자세한 내용 in this blog post

+0

와우 .. 간단했다. 감사! 나는 $ P 때문에 그것의 많은 것을 정말로 생각하지 않았다! JSP-Tomcat-Servlet 애플리케이션에서 잘 작동하는 것처럼 보였다. 둘 중 하나가 다른 JasperReports를 사용하거나 JasperReports 메소드를 직접 호출하는 것보다 다른 방식으로 JasperReports를 사용한다고 가정합니다. – Rich

관련 문제