ColdFusion是否不能返回一个有效的UTF-8 JSON对象?



我有一个CFC脚本,它返回一个结构体,转换成JSON格式。这是方法声明:

<CFFUNCTION name="getJSON" returntype="Struct" returnformat="JSON" output="no" access="remote">

输出看起来很好,但不是UTF-8格式。

我已经试过了:

<CFCONTENT type="application/json; charset=utf-8">
<CFPROCESSINGDIRECTIVE pageEncoding="utf-8">
<CFSCRIPT>
SetEncoding("url", "utf-8");
SetEncoding("form", "utf-8");
</CFSCRIPT>

并且我将。cfc文件保存为带有BOM的UTF-8。

我想用这个作为Jasper报告的数据源,但是我总是得到这个错误信息:

Invalid UTF-8 middle byte 0x74
at [Source: java.io.ByteArrayInputStream@6c2071a7; line: 1, column: 745]

JSON数据包含德语变音符。第一个在这个位置:"line: 1, column: 745"

创建数据源时发生错误。输入流不是UTF-8格式。

jsonUrl = getParam('JSON_URL', ReportParamArray);
inputStream = CreateObject("java", "java.net.URL").init(jsonUrl).openConnection().getInputStream();
jasperPrint = jasFillManager.fillReport(jasReport, parameters,
                CreateObject("java", "net.sf.jasperreports.engine.data.JsonDataSource").init(inputStream));

这是完整的Stacktrace:

    Error evaluating expression :
Source text : ((net.sf.jasperreports.engine.data.JsonDataSource) $P{REPORT_DATA_SOURCE}).subDataSource("ARBEITSRAPPORT")
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1284):1284
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:588):588
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidOther(UTF8StreamJsonParser.java:2832):2832
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidOther(UTF8StreamJsonParser.java:2839):2839
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._decodeUtf8_3fast(UTF8StreamJsonParser.java:2661):2661
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:1962):1962
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString(UTF8StreamJsonParser.java:1911):1911
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:276):276
at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:203):203
at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:58):58
at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:15):15
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2580):2580
at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:1500):1500
at net.sf.jasperreports.engine.data.JsonDataSource.(JsonDataSource.java:101):101
at net.sf.jasperreports.engine.data.JsonDataSource.subDataSource(JsonDataSource.java:448):448
at rechnungen_1441802385613_104250.evaluate(rechnungen_1441802385613_104250:415):415
at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:231):231
at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:591):591
at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:559):559
at net.sf.jasperreports.engine.fill.JRFillElement.evaluateExpression(JRFillElement.java:1001):1001
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:392):392
at net.sf.jasperreports.components.table.fill.FillTableSubreport.evaluateSubreport(FillTableSubreport.java:101):101
at net.sf.jasperreports.components.table.fill.FillTable.evaluate(FillTable.java:117):117
at net.sf.jasperreports.engine.fill.JRFillComponentElement.evaluate(JRFillComponentElement.java:108):108
at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:259):259
at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:456):456
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2044):2044
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:778):778
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:288):288
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:151):151
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:932):932
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:864):864
at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:88):88
at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:653):653
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:969):969
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method):-2
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source):-1
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source):-1
at java.lang.reflect.Method.invoke(Unknown Source):-1
at lucee.runtime.reflection.pairs.MethodInstance.invoke(MethodInstance.java:55):55
at lucee.runtime.java.JavaObject.call(JavaObject.java:234):234
at lucee.runtime.java.JavaObject.call(JavaObject.java:256):256
at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:742):742
at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1589):1589
at cfdocs.gebman.reports.reportsystemjasper_cfm$cf.call(D:ICSInternetCFDOCSgebmanreportsreportSystemJasper.cfm:158):158
at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:950):950
at lucee.runtime.tag.CFTag.doInclude(CFTag.java:323):323
at lucee.runtime.tag.CFTag.cfmlStartTag(CFTag.java:245):245
at lucee.runtime.tag.CFTag.doStartTag(CFTag.java:177):177
at cfdocs.gebman.reports.rechnungindex_cfm$cf.call(D:ICSInternetCFDOCSgebmanreportsrechnungIndex.cfm:151):151
at lucee.runtime.PageContextImpl.doInclude(PageContextImpl.java:950):950
at lucee.runtime.listener.ClassicAppListener._onRequest(ClassicAppListener.java:56):56
at lucee.runtime.listener.MixedAppListener.onRequest(MixedAppListener.java:36):36
at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2257):2257
at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2224):2224
at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:456):456
at lucee.loader.servlet.CFMLServlet.service(CFMLServlet.java:47):47
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728):728
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305):305
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210):210
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222):222
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123):123
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472):472
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171):171
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99):99
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118):118
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407):407
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004):1004
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589):589
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310):310
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source):-1
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source):-1
at java.lang.Thread.run(Unknown Source):-1

我如何确保CFC返回有效的UTF-8内容?

在Leigh的帮助下,我解决了这个问题。getInputStream()函数没有使用UTF-8。甚至当我将默认的文件编码设置为UTF-8时,它也不起作用。

为了确保报表生成器使用UTF-8,我重新创建了输入流并在流程中应用了编码。

jsonUrl = getParam('JSON_URL', ReportParamArray);
// Get the Input Stream
inputStream = CreateObject("java", "java.net.URL").init(jsonUrl).openConnection().getInputStream();
// Convert the stream to a byte array
bytes = CreateObject("java", "org.apache.commons.io.IOUtils").toByteArray(inputStream);
// Convert bytes to string
str = CreateObject("java", "java.lang.String").init(bytes);
// Create a new UTF-8 input stream
inputStreamUTF8 = CreateObject("java", "java.io.ByteArrayInputStream").init(str.getBytes("UTF-8"));
// Fill the report with our new input stream
jasperPrint = jasFillManager.fillReport(jasReport, parameters,
    CreateObject("java", "net.sf.jasperreports.engine.data.JsonDataSource").init(inputStreamUTF8));

就性能而言,这可能不是完美的解决方案,但它可以工作,并且我逃脱了编码的地狱

最新更新