【发布时间】:2021-05-17 18:26:19
【问题描述】:
我正在尝试使用 ColdFusion 10 设置一些 REST Web 服务,如果我在 Application.cfc 中有一个 onError 处理程序,则错误状态代码不会返回给消费者。
让我们考虑一下这个 Application.cfc
<cfcomponent displayname="ApplicationCFC" output="true" >
<cfscript>
this.name = "learnWith";
this.applicationTimeout = createTimeSpan(1,1,0,0);
this.sessionManagement = "false";
this.restsettings.autoregister = true;
this.restsettings.skipCFCWithError = true;
</cfscript>
<cffunction name="onApplicationStart" returntype="boolean" output="true">
<cfset RestInitApplication(expandPath('/myDir'),"lw")>
<cfreturn true>
</cffunction>
</cfcomponent>
现在考虑服务,如下所示:
<cfcomponent rest="true" restpath="/user">
<cffunction name="authenticate" access="remote" restpath="/login" returntype="String" httpmethod="POST"
consumes="application/json" produces="application/json">
<cfset requestData = getHTTPRequestData()>
<cfset userInfo = deserializeJSON(ToString(requestData.content)) />
<!--- cfquery to load user data ---->
<cfif local.dataQuery.recordcount EQ 1>
<cfset local.userVO = createObject()> <!--- create and populate userVo here --->
<cfreturn SerializeJSON(local.userVO)>
<cfelse>
<!--- user not found, throw 401 error --->
<cfthrow type="RestError" errorcode="401" />
</cfif>
</cffunction>
</cfcomponent>
此代码在 Postman 中完美运行。如果我传入正确的凭据
{
"userName": "user",
"password": "hashedPassword
}
我按预期返回了一个用户对象,响应为 200。
如果我传递了虚假或无效的凭据:
{
"userName": "fakeuser",
"password": "fakePassword
}
我收到 401 错误:
太完美了。但是,我想为 CFC 使用全局错误处理程序,既用于基于非 REST 服务的代码,也用于记录可能的 REST 服务错误。如果我将其添加到 Application.cfc
<cffunction name="onError" returnType="void" output="true">
<cfargument name="exception" required="true">
<cfargument name="eventname" type="string" required="true">
<!--- error logging here --->
<cfthrow type="RestError" errorcode="401" />
<!--- or
<cfthrow type="#arguments.exception.Cause.Cause.type#"
errorcode="#arguments.exception.Cause.Cause.code#">--->
</cffunction>
ColdFusion 返回 500 内部服务器错误消息。
我在 CFC 方法和 onError 处理程序中都尝试了 cfheader:
<cfheader statusCode = "401" statusText = "RestError">
它将返回没有正文的 200 而不是 401 状态:
我已经尝试了各种迭代,但不知所措。我可以使用来自 ColdFusion 休息服务的状态代码,同时还有一个 onError 处理程序吗?如果有,怎么做?
【问题讨论】:
-
我认为问题可能在于您的
onError方法<cfthrow type="RestError" errorcode="401" />中有此代码。要调用的onError方法已经发生错误,并且您正在从错误处理程序中抛出另一个错误。我认为您应该能够在onError方法中使用<cfheader statuscode="401" statustext="Unauthorized" />来返回特定的 HTTP 状态代码。但不要使用cfthrow。至少不在onError方法本身内。 -
@Miguel-F 如果我删除 cfthrow 并且有一个没有代码的 onError 方法,我仍然没有在服务器上返回 401。该解决方案似乎是使用
restSetResponse()发回响应而不使用 cfthrow 或返回项目。我会发布更深入的内容。 -
您发布的答案是比引发错误更好的解决方案,但要明确的是,我并不是要您尝试没有代码的 onError 方法。你仍然需要我提到的
<cfheader ...>代码。无论如何,很高兴你能成功。 -
@Miguel-F cfheader 在使用 CF 的 REST API 时无论是在 onError 方法还是 CFC 方法中都没有影响。我在最初的问题中指出了这一点。
标签: rest coldfusion coldfusion-10 application.cfc