我想知道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 Loader)时,文本区域上的文本为:
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 Loader)时,文本区域上的文本为:
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状态代码。
我认为运行时存在问题,对吧?我很感激你对此事的评论。
答案 0 :(得分:0)
我认为这里有一些误解可以先解决:
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正在打开一个错误发生的对话框。
这是猜测,因为我找不到任何文档,但我发现HTTPService
将ResultEvent : 401
更改为FaultEvent : 401
(因此将其转换为{{1}并不会让我感到惊讶错误)利用调试错误对话框。