我们最近经历了从CF11升级到CF2023的过程。在我们的开发服务器上,一切似乎都按预期进行。然而,在我们的生产服务器上安装后,我们发现了一个奇怪的问题。
cfc 文件中的
fileRead
命令似乎读取该文件,但在 cfc 处理完成后抛出 500 错误。任何其他 cfc 中的任何其他命令(我们尚未发现)都不会出现此问题。我可以在我们的生产服务器上重现这个问题;但在开发(或测试)中使用相同的测试页面,代码可以正常工作。
我们立即的解决方法是使用
cffile action="read"
。这似乎在开发和生产中工作得很好。
在开发中工作但在生产中不起作用的示例测试代码(读取文件,根据代码转储内容,但随后 500 错误覆盖在文件转储上)- fileReadTest.cfc:
component {
struct function getRules() {
try {
var _rules = fileRead('[path]/configuration.json');
_rules = deserializeJSON(_rules);
return _rules;
} catch( any e) {
cfdump( var = e);
}
}
remote string function test() {
try {
var _r = getRules()
cfdump(var = _r);
return 'test'
} catch( any e) {
cfdump( var = e);
}
}
}
这些测试是通过 url 调用(用于测试目的),并将方法作为参数:
https://ourdoman.edu/fileReadTest.cfc?method=test
我有权访问 Coldfusion 管理员页面。我通过“设置摘要”页面将产品与开发进行了比较,一切似乎都一致。我无法访问 IIS,但我确信这些设置在服务器之间是匹配的。
需要注意的一件事是我们的开发服务器无法从网络外部访问。换句话说,你必须在校园内才能使用 dev。
在查看 Coldfusion-error.log 时,我可以看到
SEVERE: Servlet.service() for servlet [CFCServlet] in context with path [] threw exception
这似乎与生成 500 错误的时间一致。查找该错误似乎会导致 IIS 问题,但我没有看到任何明确的信息可以指示我们的网络管理员进行检查。
任何见解都会非常有帮助。虽然我们可以使用 cffile 作为解决方法,但我担心这是更大配置问题的迹象。
谢谢
编辑:
重现错误的代码精简版:
component {
string function getRules() {
var _rules = fileRead('c:/applications/test/test.txt');
return _rules;
}
remote string function test() {
var _r = getRules();
return _r;
}
}
test.txt = 这是一个测试。
更新: 作为测试,我尝试使用 fileRead 读取 fileOpen 返回的 fileObject。例如:
var x = fileOpen('[path]/test.txt')
var y = fileRead(x, 16);
fileClose(x);
结果是一样的。文件被读取并输出(参见上面的示例代码),但随后显示 500 错误。如果我取出 fileRead,fileOpen 和 fileClose 似乎可以正常工作。
另外,有人建议我查看 application.cfc onRequestStart / onRequestEnd。我可以验证它们是否正常执行 - 作为测试,我让它们在每次开始和结束时发送一封电子邮件。另外,如果发生错误,application.cfc 中的 onError 也会发送电子邮件。
测试更新
在我的测试 cfc 中,我创建了一个循环来迭代调用 fileRead 的函数。每次迭代都会成功调用 fileRead,如 cfdump 的数据所示。一旦迭代完成,就会产生500错误。
回复
我认为查看控制台响应可能会有所帮助。例如,如果文件是“这是一个测试”,则响应如下所示。首先是文件内容,然后将 500 错误附加到响应中。
<wddxPacket version='1.0'>
<header/>
<data>
<string>
this is a test<char code='0d'/>
<char code='0a'/>
</string>
</data>
</wddxPacket>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>500</title>
<style>
body {
...
有线索吗?
一个重要的线索(?):如果从 .cfm 调用执行 fileRead 的 .cfc,使用
cfhttp
、createObject
、invoke
,它可以正常工作,不会出现错误。但是,如果通过 [URL]/test.cfc?method=getData
或(正如应用程序最初所做的那样)通过 $http
(AngularJS) 调用,则会生成错误。这两种方法都使用相同的 URL。如果从另一个cfc
调用它也会失败。
另一个花絮
FileWrite
的行为方式与 FileRead
相同。当从 .cfc 调用时,它会写入文件,但随后抛出 500 错误。
堆栈跟踪
Jul 11, 2023 1:08:07 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [CFCServlet] in context with path [] threw exception
java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.get(Optional.java:143)
at coldfusion.monitor.beans.RequestData.isGraphQlService(RequestData.java:795)
at coldfusion.monitor.beans.RequestData.updateFunctionMetrics(RequestData.java:618)
at coldfusion.monitor.beans.RequestData.updateTagData(RequestData.java:459)
at coldfusion.monitor.beans.RequestData.updateData(RequestData.java:223)
at coldfusion.monitor.event.RequestMonitorEventProcessor.onRequestEnd(RequestMonitorEventProcessor.java:419)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:82)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:47)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:373)
at org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:459)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
鉴于数十条评论中所说的内容(或您原来的和目前仅的其他答案),我想知道如果您尝试将 returnformat 查询字符串作为 URL 添加到 CFC 的调用中,以更改返回内容的格式。例如,您可以尝试
https://ourdoman.edu/fileReadTest.cfc?method=test&returnformat=plain
,或 returnformat=json
。
您可能知道,CF 默认返回 wddx(即 xml)之类的结果。也许这在某种程度上导致了你的问题。我无法理解那可能是什么,但它至少可以给你/我们一个线索。如果某种变体以某种方式工作得更好,您还可以将“正确”
returnformat
设置为方法定义上的同名参数。 (我在 2017 年有一篇博客文章介绍了如何在基于脚本的函数定义中做到这一点。需要明确的是,我确实看到您将 test
函数的返回类型定义为 string
,这是一个单独的问题.)无论哪种方式,听听这是否有帮助都会很有趣。