【问题标题】:Grails - Jasper Plugin - Invalid byte 1 of 1-byte UTF-8 sequence error with .jasper fileGrails - Jasper 插件 - .jasper 文件的 1 字节 UTF-8 序列的无效字节 1 错误
【发布时间】:2013-11-26 08:41:53
【问题描述】:

我正在使用 Grails 1.3.5、SQL Server 2005、iReports 3.7.6、Jasper 插件 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'

新建和保存新报表时,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!!! :)

我已经在生产模式下测试过它,它工作正常。我不确定这是否是这样做的方法,但所有其他可能的解决方案都不适合我。

反馈会很有帮助。

【问题讨论】:

  • 感谢您针对字符编码问题提供的解决方法,我仍在调查它是否是正确的解决方案
  • 我已选择将编译后的.jasper的目录更改为c\windows\temp,以避免手动删除文件。

标签: grails grails-plugin jasper-plugin


【解决方案1】:

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

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

关于子报告:不知道。

【讨论】:

  • 感谢您的回复。我已经更新了我的问题。使用我更新的问题中提到的解决方法,事情开始对我有用。但不确定这是否是最好的方法。
【解决方案2】:

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 了解替代配置。

至于子报表的错误,请看反斜杠\,这可能是错误的。

【讨论】:

  • 感谢您的回复。我不确定 Jasper 的 etc/ireport.conf 文件。我已经更新了我的问题。
  • 我已经用文件编码选项更新了 C:\Archivos de programa\Jaspersoft\iReport-4.1.3\etc\ireport.conf(配置窗口的相关位置)并且不起作用跨度>
【解决方案3】:

编辑:有一些关于两个问题的信息可能有助于 http://grails.org/plugin/jasper#faqTab

我希望我能帮助解决其中一个问题:哪一个与子报表目录有关。 问题是插件代码将 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 的隐藏输入并设置所需的值。我会以其他方式填写参数。

编辑: 另一个烦人的问题是我们必须把主报告和编译的子报告放在哪里:

  • 但是,如果您想部署战争,您必须将主要报告放在战争文件根目录下的文件夹 reportDir 中在 WEB-INF/classes/reportDir 中编译子报告。

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

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")
    }
} 

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-10
    • 2018-12-26
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 2013-12-10
    • 2013-03-10
    相关资源
    最近更新 更多