【问题标题】:Flex's HTTPService dispatches a ResultEvent instead of a FaultEventFlex 的 HTTPService 调度一个 ResultEvent 而不是一个 FaultEvent
【发布时间】:2014-05-26 18:32:08
【问题描述】:

我想知道 Flex 的 HTTPService 什么时候启动一个 ResultEvent,什么时候分派一个 FaultEvent。

当服务器响应包含 401 http 状态代码错误(未授权)时,HTTPService 将调度 ResultEvent 而不是 FaultEvent。我会假设它应该调度一个 FaultEvent。我对么?如果没有请告诉我。

令人惊奇的是,当我在 Flash Builder 4.7 的 Android 模拟器下运行应用程序时,它确实调度了一个 FaultEvent,但是当我在设备上运行它时,它调度了 ResultEvent。为什么会这样?有什么想法吗?

测试应用代码

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">

   <fx:Script>
    <![CDATA[
        import mx.rpc.events.FaultEvent;
        import mx.rpc.events.ResultEvent;

        ///////////////////////////// USING HIGH LEVEL COMPONENT (FLEX) //////////////////////////////////////////

        /**
         * Checks if all the necesary data was entered by the user.
         */
        protected function configHandler(event:MouseEvent):void
        {
            textArea.text = "Connecting to server using a high level component";
            configurationService.url = "http://10.0.0.221/api/v1/room/current/";
            configurationService.headers.Accept = "application/json";  
            configurationService.send();
            textArea.appendText("\n...");
        }

        /**
         * Handles the first phase (getting basic application information) of the configuration. 
         * Stores the retrieved data from the server and calls the second phase of the process.
         */
        protected function serviceResultHandler(event:ResultEvent):void
        {
            textArea.appendText("\n");
            textArea.appendText("Entering serviceResultHandler \n");
            textArea.appendText(" HTTP status code is: " + event.statusCode);
        }

        /**
         * Handles errors within the first phase (getting basic application information) of the configuration process.
         */
        protected function servicefaultHandler(event:FaultEvent):void
        {
            textArea.appendText("\n");
            textArea.appendText("Entering servicefaultHandler \n");
            textArea.appendText("HTTP status code is: " + event.statusCode);
        }

        ///////////////////////////// USING LOW LEVEL COMPONENT (FLASH) //////////////////////////////////////////

        /**
         * Checks if all the necesary data was entered by the user.
         */
        protected function config2Handler(event:MouseEvent):void
        {
            textArea.text = "Connecting to server using a low level component \n ...";

            var loader:URLLoader = new URLLoader();
            var request:URLRequest = new URLRequest("http://10.0.0.221/api/v1/room/current/");
            request.requestHeaders = new Array( new URLRequestHeader('Accept','application/json'));

            try {
                loader.load(request);
            } catch (error:Error) {
                trace("Unable to load requested document.");
            }

            loader.addEventListener(Event.COMPLETE, completeHandler);
            loader.addEventListener(Event.OPEN, openHandler);
            loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

        private function completeHandler(event:Event):void {
            var loader:URLLoader = URLLoader(event.target);
            textArea.appendText("\n");
            textArea.appendText("Entering completeHandler \n");
            textArea.appendText("completeHandler: " + loader.data + "\n");

            var vars:URLVariables = new URLVariables(loader.data);
            textArea.appendText("The answer is " + vars.answer);
        }

        private function openHandler(event:Event):void {
            textArea.appendText("\n");
            textArea.appendText("Entering openHandler \n");
            textArea.appendText("openHandler: " + event);
        }

        private function progressHandler(event:ProgressEvent):void {
            textArea.appendText("\n");
            textArea.appendText("Entering progressHandler \n");
            textArea.appendText("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
        }

        private function securityErrorHandler(event:SecurityErrorEvent):void {
            textArea.appendText("\n");
            textArea.appendText("Entering securityErrorHandler \n");
            textArea.appendText("securityErrorHandler: " + event);
        }

        private function httpStatusHandler(event:HTTPStatusEvent):void {
            textArea.appendText("\n");
            textArea.appendText("Entering httpStatusHandler \n");
            textArea.appendText("httpStatusHandler: " + event);
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
            textArea.appendText("\n");
            textArea.appendText("Entering ioErrorHandler \n");
            textArea.appendText("ioErrorHandler: " + event);
        }

    ]]>
   </fx:Script>

    <fx:Declarations>
        <s:HTTPService id="configurationService"
                   result="serviceResultHandler(event)" fault="servicefaultHandler(event)"/>
    </fx:Declarations>

    <s:Button label="High Level" click="configHandler(event)"
          horizontalCenter="100" top="20" />
    <s:Button label="Low Level" click="config2Handler(event)"
          horizontalCenter="-100" top="20"/>
    <s:TextArea id="textArea"
            left="20" right="20" top="{configButton.y + configButton.height + 20}" bottom="20"/>
</s:View>

Flash Builder 模拟器上的结果

  • 当按下“低级”按钮(URL 加载器)时,文本区域上的文本是:

    Connecting to server using a low level component
    ...
    Entering openHandler 
    openHandler: [Event type="open" bubbles=false cancelable=false eventPhase=2] 
    Entering httpStatusHandler 
    httpStatusHandler: [HTTPStatusEvent type="httpStatus" bubbles=false cancelable=false eventPhase=2    status=401 responseURL=null] 
    Entering ioErrorHandler 
    ioErrorHandler: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error  #2032: Stream Error. URL: http://10.0.0.221/api/v1/room/current/" errorID=2032]
    
  • 当按下“高级”按钮(HTTPService)时,文本区域的文本是:

    Connecting to server using a high level component 
    ... 
    Entering servicefaultHandler
    HTTP status code is: 401
    

Android 设备上的结果

  • 当按下“低级”按钮(URL 加载器)时,文本区域上的文本为:

    Connecting to server using a low level component 
    ... 
    Entering openHandler 
    openHandler: [Event type="open" bubbles=false cancelable=false eventPhase=2] 
    Entering httpStatusHandler 
    httpStatusHandler: [HTTPStatusEvent type="httpStatus" bubbles=false cancelable=false eventPhase=2    status=401 redirected=false responseURL=null] 
    Entering completeHandler 
    completeHandler: 
    
  • 当按下“高级”按钮(HTTPService)时,文本区域的文本是:

    Connecting to server using a high level component 
    ... 
    Entering serviceResultHandler
    HTTP status code is: 401
    

当我在 Flash Builder 的模拟器上运行应用程序时,两个组件都按预期工作,这意味着它们分派了一个 FaultEvent 和一个 IOErrorEvent。在 Android 设备上,每个组件行为异常,第一个调度 ResultEvent,第二个调度 Event.COMPLETE 事件。

请注意,在这两种情况下,两个组件都会感知正确的 HTTP 状态代码。

我会假设运行时存在问题,对吗?我会很感激你的 cmets 在这件事上。

【问题讨论】:

  • 能否把代码贴出来

标签: android actionscript-3 apache-flex air flex-mobile


【解决方案1】:

我认为这里有一些误解需要先澄清:

ResultEvent means "HTTPService call returns successfully." 但是这个意义上的成功意味着我们设法实现了连接并收到了响应。

服务器响应任何 HTTP 状态码是完全有效的,在本例中为 Status 401 - Unauthorized,表示您已到达服务器但尝试访问您无权访问的位置。

FaultEvent means "HTTPService call fails"。但是这里的失败是没有建立连接或没有收到响应。

FaultEvent 的更多内容是Fault 错误类的事件包装器,它“表示远程过程调用 (RPC) 服务调用中的错误”。最常见的变体是IOError #2032: Stream Error,它因模棱两可而臭名昭著。

现在谈谈为什么你的调试器和发布的版本之间的行为不同:

Capabilities.isDebugger 为真时,Flash 以不同方式处理错误。一个documented example 正在为发生错误打开一个对话框。

这是推测,因为我找不到任何文档,但我不会惊讶地发现 HTTPServiceResultEvent : 401 更改为 FaultEvent : 401(因此将其转换为 Fault 错误)以利用调试错误对话框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2018-02-10
    • 2018-04-15
    相关资源
    最近更新 更多