Grails - Jasper插件 - 带有.jasper文件的1字节UTF-8序列错误的字节1无效

时间:2010-11-26 20:04:44

标签: grails grails-plugin jasper-plugin

我使用的是Grails 1.3.5,SQL Server 2005,iReports 3.7.6,Jasper Plugin 1.1.3。在我的GSP页面中,我将jasperReprt标记指定为:

<g:jasperReport jasper="report1" format="PDF">
<input type="hidden" name="test_id" id="test_id"/>
<input type="hidden" name="order_no" id="order_no" />   
</g:jasperReport>

对于开发,在Config.groovy中我指定了

jasper.dir.reports = './reports'

创建并保存新报告时,报告文件夹中创建了两个文件,即report.jrxml和report.jasper。

点击IE或Firefox中的PDF图标时,会抛出500个服务器错误,下面是堆栈跟踪。

[2010-11-27 01:13:14.998] ERROR groovy.grails.web.errors.GrailsExceptionResolver Invalid byte 1 of 1-byte UTF-8 sequence. com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence. at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:684) at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:554) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1742) at

但如果删除report1.jasper,则单击PDF图标并且PDF报告显示正常时,不再抛出错误。

这是正确的方法吗?

  • 我的第二个问题是使用子报告。子报告与主报告位于同一文件夹中。但是当从应用程序执行报告时,会抛出以下错误:

    [2010-11-27 01:30:27.556] ERROR groovy.grails.web.errors.GrailsExceptionResolver Could not load object from location : ./reports\report1sub_report.jasper net.sf.jasperreports.engine.JRException: Could not load object from location : ./reports\urine_routinepatient_details_sub_report.jasper at net.sf.jasperreports.engine.util.JRLoader.loadObjectFromLocation(JRLoader.java:262) at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateReport(JRFillSubreport.java:301) at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:327)

找不到子报告。我该如何解决?

谢谢。 杰伊钱德兰。

修改 我一直在寻找,但仍然找不到合适的解决方案。所以我做了一些试验和错误。我发现,删除report1.jasper并在报告目录中保留jasper.jrxml就可以正常工作了。

对于子报告问题:它提供了错误Could not load object from location : ./reports\report1sub_report.jasper由于某些奇怪的原因,主报告名称report被附加到名称sub_report.jasper并正在查找文件名为report1sub_report.jasper

所以我在reports文件夹下创建了一个子文件夹,并将其命名为report1并更新了report1.jrxml文件

<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "\\sub_report.jasper"]]></subreportExpression>

我必须添加额外的\\斜杠,即使“SUBREPORT_DIR”参数在路径末尾有斜杠\\,如下所示。

<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
    <defaultValueExpression><![CDATA["F:\\Workspace\\SpringSource2.5.0\\GrailsProjec\\reports\\report1\\"]]></defaultValueExpression>
</parameter>

注意最后的\\。我不知道为什么没有附加!

另一种方法是将子报告名称从sub_report.jasper 更改为report1sub_report.jasper! :)

我在生产模式下对此进行了测试,效果很好。我不确定这是否是这样做的方法,但所有其他可能的解决方案对我来说都不起作用。

反馈将非常有用。

3 个答案:

答案 0 :(得分:0)

我假设您在此处存在版本冲突。 iReport存储JRXML文件,似乎自动将它们编译为.jasper。 Grails Jasper插件选择了编译变体并遇到麻烦。所以尝试在ireport中禁用编译输出。

Grails Jasper插件1.1.3内部使用Jasper 3.7.4,使用的ireport为3.7.6。

关于子报告:不知道。

答案 1 :(得分:0)

MalformedByteSequenceException是由字符编码冲突引起的。我建议在任何地方使用UTF-8而不是Windows的Win-1252(类似于ISO-8859-1)。

在Jasper的 etc / ireport.conf 文件中,将default_options更改为:

default_options="-J-Dfile.encoding=UTF-8 -J-Xms24m -J-Xmx64m"

(其中XmsXmx是不相关的内存设置。如果有该配置条目的默认设置,您可以超越它们,否则,只需将它们删除。)

有关替代配置,请参阅this forum thread

对于子报表的错误,请查看可能错误的反斜杠\

答案 2 :(得分:0)

编辑:有一些信息可能会有所帮助 http://grails.org/plugin/jasper#faqTab

我希望我可以帮助解决其中一个问题:与子报告dir相关的问题。 问题是插件代码将SUBREPORT_DIR设置为主报告的完整文件路径,包括其名称。但是代码尊重用户提供的具有相同名称的参数,因此如果您使用除null之外的任何值填充此参数,插件将使用它。

例如,如果你直接链接jasper控制器,你可以这样做:

def renderAs(data,format) {
    def reportParams=params.clone()
    reportParams["_format"]=reportParams["_format"]?:"${format.toUpperCase()}"
    reportParams["SUBREPORT_DIR"]=CH.config.jasper.dir.reports+"/"
    chain(controller:'jasper',action:'index',model:[data:[]+data],params:reportParams)
}

在您的场景中,(丑陋)选项将创建一个名为SUBREPORT_DIR的隐藏输入,并为所需值输入值。我会以其他方式填写参数。

修改: 另一个恼人的问题是我们必须在哪里放置主报告和编译的子报告:

  • 当您使用run-app运行应用程序时,如果您将它们全部放在与grails应用程序根目录中的CH.config.jasper.dir.reports(reportDir)同名的文件夹中,则它们可以正常工作。
  • 但是如果要部署战争,则必须将主报告放在war-file文件编译子报告的WEB-INF / classes / reportDir中的文件夹reportDir中。

我选择将所有文件保存在grailsApp / reports中,并将资源复制到war grails任务中的appropiate文件夹中。在我添加的BuildConfig.groovy中(reportDir是“报告”):

grails.war.resources = { stagingDir,args ->
    def classpathDir="${stagingDir}/WEB-INF/classes"
    copy(toDir:"${stagingDir}/reports") {
        fileset(dir:"reports",includes:"**")
    }
    copy(toDir:"${classpathDir}/reports") {
        fileset(dir:"reports",excludes:"**.jrxml")
    }
} 

希望它有所帮助。