使用 OnError 处理程序时如何 return 来自 REST 服务的状态代码错误?

How do I return a status code error from a REST Service while using an OnError handler?

我正在尝试使用 ColdFusion 10 设置一些 REST Web 服务,如果我在 Application.cfc 中有一个 onError 处理程序,则错误状态代码不会 return 返回到给消费者。

让我们考虑一下这个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
}

我得到了一个用户 object,如预期的那样返回 200 响应。

如果我输入虚假或无效的凭据:

{
    "userName": "fakeuser",
    "password": "fakePassword
}

我返回 401 错误:

太完美了。但是,我想为 CFC 使用全局错误处理程序,既用于 non-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 return500 内部服务器错误消息。

我在 CFC 方法和 onError 处理程序中试验了 cfheader:

<cfheader statusCode = "401" statusText = "RestError">

它将 return 没有 body 的 200 而不是 401 状态:

我已经尝试过各种迭代,但不知所措。我可以使用来自 ColdFusion 休息服务的状态代码,同时还有一个 onError 处理程序吗?如果是,怎么做?

我能够做我想做的事。我可以使用 restSetResponse.

创建我需要的响应,而不是使用 cfthrow 创建错误

在 cffunction 内部,首先确保将 return 类型设置为 void。

那么您希望手动创建一个响应对象并使用 restSetResponse.

将其发回,而不是 returning 对象或使用 cfthrow

这解决了我的问题:

<cfcomponent rest="true" restpath="/user">
    <cffunction name="authenticate" access="remote" restpath="/login" returntype="void" httpmethod="POST"
            consumes="application/json" produces="application/json">
        <cfset requestData = getHTTPRequestData()>
        <cfset userInfo = deserializeJSON(ToString(requestData.content)) />

        <!--- cfquery to load user data ---->

        <cfset local.result = structNew()/>

        <cfif local.dataQuery.recordcount EQ 1>
            <cfset local.userVO = createObject()> <!--- create and populate userVo here --->

            <cfset local.result.status = 200 />
            <cfset local.result.content = SerializeJSON(local.userVO) />
        <cfelse>
            <cfset local.result.status = 401 />
            <cfset local.result.content = SerializeJSON({message: 'User Not Authorized'}) />
        </cfif>

        <cfset restSetResponse(local.result) />
    </cffunction>
</cfcomponent>

一旦我这样做了,我就能够在不触发 Application.cfc.

中的 onError 方法的情况下控制对消费者的响应