Hay varios filtros de serialización personalizados que pueden facilitar su vida (requiere Flex 4).
Implementación del patrón de diseño compuesto para filtros de serialización HTTP . Anular cualquiera de los 5 métodos de SerializationFilter utilizando diferentes instancias de filtro:
<mx:HTTPService>
<mx:serializationFilter>
<rest:CompositeSerializationFilter>
<!-- Serialize requests in JSON -->
<rest:bodySerializer>
<rest:JSONSerializationFilter />
</rest:bodySerializer>
<!-- Deserialize replies in JSON -->
<rest:resultDeserializer>
<rest:JSONSerializationFilter />
</rest:resultDeserializer>
<!-- Build REST-style URLs dynamically -->
<rest:urlSerializer>
<rest:RESTSerializationFilter />
</rest:urlSerializer>
<!-- Use custom HTTP methods -->
<rest:parametersSerializer>
<rest:RESTSerializationFilter />
</rest:parametersSerializer>
<!-- Set request content type to application/json -->
<rest:contentTypeProvider>
<rest:RESTSerializationFilter requestContentType="application/json" />
</rest:contentTypeProvider>
</rest:CompositeSerializationFilter>
</mx:serializationFilter>
</mx:HTTPMultiService>Los métodos de serializationFilter que se pueden anular:
deserializeResultgetRequestContentTypeserializeParametersserializeBodyserializeURLLos métodos que no se anulan se manejan utilizando un Filter de Serialization regular.
Implementa los métodos serializeParameters , contentTypeProvider y serializeURL .
Le permite enviar verbos HTTP personalizados, que no sean Get o Post , que no es compatible con el reproductor Flash de forma predeterminada. Puede especificar una de las tres formas posibles de hacerlo:
methodOverride="header" ). No olvide actualizar su archivo CrossDomain.xml para permitir que los encabezados se envíen a otros dominios._method a todas las URL ( methodOverride="url" )._method ( methodOverride="variable" ). Esto obligará a su solicitud a ser serializada como application/x-www-form-urlencoded .Este filtro de serialización también se puede utilizar para construir URL dinámicas que contemplen los parámetros tokenizados (encerrados en soportes cuadrados).
<fx:Declarations>
<rest:RESTSerializationFilter
id="restSerializer"
methodOverride="variable"
requestContentType="application/x-www-form-urlencoded" />
<mx:HTTPMultiService
id="service"
baseURL="http://example.com/api/"
>
<mx:serializationFilter>
<!-- contentTypeProvider is required in order to convert custom HTTP verbs to POST
and to set content type to 'application/x-www-form-urlencoded'. -->
<!-- urlSerializer will replace square bracket tokens in URLs. -->
<!-- parametersSerializer will add a '_method' variable to your requests, if needed. -->
<rest:CompositeSerializationFilter
contentTypeProvider="{restSerializer}"
urlSerializer="{restSerializer}"
parametersSerializer="{restSerializer}" />
</mx:serializationFilter>
<mx:operationList>
<!--
[ID] and any other token will be automatically
replaced by variables from operation arguments object
-->
<mx:HTTPOperation
name="getUser"
url="User/[ID]" />
<!--
Request will be sent as a POST request
with a "_method"="DELETE" variable
-->
<mx:HTTPOperation
name="deleteUser"
url="User/[ID]"
method="DELETE" />
</mx:operationList>
</mx:HTTPMultiService>
</fx:Declarations> import mx.rpc.AbstractOperation;
import mx.rpc.AsyncToken;
import vo.User;
private function getUser(userId:uint):AsyncToken
{
var operation:AbstractOperation = service.getOperation("getUser");
operation.arguments = { ID: userId }; //replace URL tokens
return operation.send();
//You can also add your variable to requests:
//return operation.send({ varname: "varvalue" });
} Implementa los métodos deserializeResult , contentTypeProvider y serializeBody .
Solicitudes de serialize y respuestas de deserialización en JSON con un analizador JSON nativo rápido (solo en la versión FP11; la versión FP9 se basa en el analizador JSON de AS3Corelib). Las solicitudes y respuestas se pueden convertir desde y en objetos fuertemente tipados sobre la mosca. Las siguientes funciones de mapeo de objetos están disponibles:
ArrayElementType Metatag se puede usar para mapear las matrices de objetos escrito.Transient se respeta tanto en las solicitudes como en las respuestas./Date(1325376000000)/ se pueden convertir hasta los objetos Date , y viceversa. Por ejemplo, cuando recibe esto:
{
"owner":{
"birthday":"/Date(1325376000000)/",
"firstName":"John",
"lastName":"Smith"
}
"wheels":[
{ "position": { "x":1, "y":1 } },
{ "position": { "x":1, "y":-1 } },
{ "position": { "x":-1, "y":1 } },
{ "position": { "x":-1, "y":-1 } }
]
}
public class User
{
public var birthday:Date;
public var firstName:String;
public var lastName:String;
}
public class Car
{
public var owner:User;
[ArrayElementType("vo.Wheel")]
public var wheels:Array;
//You can just use vectors instead
//public var wheels:Vector.<Wheel>
}
import flash.geom.Point;
public class Wheel
{
public var position:Point;
} <fx:Declarations>
<mx:HTTPMultiService
id="service"
baseURL="http://example.com/api/"
>
<mx:serializationFilter>
<rest:CompositeSerializationFilter>
<!-- Serialize requests from objects to JSON. -->
<rest:bodySerializer>
<rest:JSONSerializationFilter />
</rest:bodySerializer>
<!-- Deserialize replies from JSON to strongly-typed objects. -->
<rest:resultDeserializer>
<rest:JSONSerializationFilter />
</rest:resultDeserializer>
<!-- Forces requests content type to be 'application/json'.
This is required in order to encode requests in JSON.
If content type is not changed either this way,
or manually on an operation, Flex will handle
request body encoding by itself. -->
<rest:contentTypeProvider>
<rest:RESTSerializationFilter requestContentType="application/json" />
</rest:contentTypeProvider>
<!-- This serializer is required for JSON requests. -->
<rest:parametersSerializer>
<rest:RESTSerializationFilter />
</rest:parametersSerializer>
</rest:CompositeSerializationFilter>
</mx:serializationFilter>
<mx:operationList>
<!--
Note that there is a resultElementType
property set on the operation
-->
<mx:HTTPOperation
name="getCar"
url="Car/[ID]"
method="GET"
resultElementType="{Car}"
result="onCarLoaded(event)" />
</mx:operationList>
</mx:HTTPMultiService>
</fx:Declarations> import mx.rpc.events.ResultEvent;
import vo.Car;
import vo.User;
import vo.Wheel;
private function onCarLoaded(event:ResultEvent):void
{
var car:Car = Car(event.result);
var wheels:Vector.<Wheel> = car.wheels;
var owner:User = car.owner;
var birthday:Date = owner.birthday;
} Si tiene una variedad de objetos ...
[
{ "x":1, "y":5 },
{ "x":2, "y":4 },
{ "x":3, "y":3 },
{ "x":4, "y":2 },
{ "x":5, "y":1 }
]resultFormat="array" y resultElementType="{ElementClass}" . Por defecto, todas las matrices están envueltas en una ArrayCollection . Para evitar este comportamiento, simplemente establezca makeObjectsBindable="false" en la instancia de operación. <mx:HTTPOperation
name="getPoints"
url="Points/[FROM]/[TO]"
resultFormat="array"
makeObjectsBindable="false"
resultElementType="{Point}"
result="onPointsLoaded(event)" /> private function onPointsLoaded(event:ResultEvent):void
{
trace(event.result.length);
for each(var point:Point in event.result)
trace(point.x + point.y);
} JSONSerializationFilter es una implementación de un TypedSerializationFilter de abstracto que maneja la transformación de tipos, mientras que una clase de niños concreto maneja la serialización y la deserialización de los datos reales.
Configurar resultFormat en cualquier otro valor, además de array y object (predeterminado) dará como resultado un JSONSerializationFilter (o cualquier otro TypedSerializationFilter ) para suprimirse en una HTTPOperation seleccionada.
Implementa los métodos deserializeResult , contentTypeProvider y serializeBody .
Actúa de la misma manera que el JSONSerializationFilter . Puede usar las propiedades opcionales xmlEncode y xmlDecode para asignar métodos de serialización personalizados:
<mx:HTTPService>
<mx:serializationFilter>
<rest:CompositeSerializationFilter>
<!-- Serialize requests from objects to XML. -->
<rest:bodySerializer>
<rest:XMLSerializationFilter xmlEncode="{doXmlEncode}" />
</rest:bodySerializer>
<!-- Deserialize replies from XML to strongly-typed objects. -->
<rest:resultDeserializer>
<rest:XMLSerializationFilter xmlDecode="{doXmlDecode}" />
</rest:resultDeserializer>
<!-- Forces requests content type to be 'application/xml'. -->
<rest:contentTypeProvider>
<rest:RESTSerializationFilter requestContentType="application/xml" />
</rest:contentTypeProvider>
<!-- This serializer is required for XML requests. -->
<rest:parametersSerializer>
<rest:RESTSerializationFilter />
</rest:parametersSerializer>
</rest:CompositeSerializationFilter>
</mx:serializationFilter>
</mx:HTTPMultiService> private function doXmlEncode(body:Object):XMLNode
{
return new XMLNode(1, '<body id="' + body.id + '"/>');
}
private function doXmlDecode(node:XMLNode):Object
{
return { id: node.attributes.id };
} Extiende el CompositeSerializationFilter con dos nuevas propiedades: username y password . Agregará un encabezado básico de autenticación HTTP a todas las solicitudes.
<mx:HTTPService>
<mx:serializationFilter>
<rest:BasicAuthenticationSerializationFilter username="admin" password="qwerty">
<rest:bodySerializer>
<rest:XMLSerializationFilter />
</rest:bodySerializer>
<rest:resultDeserializer>
<rest:XMLSerializationFilter />
</rest:resultDeserializer>
<rest:contentTypeProvider>
<rest:RESTSerializationFilter requestContentType="application/xml" />
</rest:contentTypeProvider>
<rest:parametersSerializer>
<rest:RESTSerializationFilter />
</rest:parametersSerializer>
</rest:BasicAuthenticationSerializationFilter>
</mx:serializationFilter>
</mx:HTTPMultiService> Extiende el CompositeSerializationFilter . Se puede usar para crear y asignar un encabezado OAuth a sus solicitudes.
<mx:HTTPService>
<mx:serializationFilter>
<rest:OAuthSerializationFilter id="oauthFilter" keySecret="kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw" tokenSecret="LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE">
<rest:bodySerializer>
<rest:XMLSerializationFilter />
</rest:bodySerializer>
<rest:resultDeserializer>
<rest:XMLSerializationFilter />
</rest:resultDeserializer>
<rest:contentTypeProvider>
<rest:RESTSerializationFilter requestContentType="application/xml" />
</rest:contentTypeProvider>
<rest:parametersSerializer>
<rest:RESTSerializationFilter />
</rest:parametersSerializer>
</rest:BasicAuthenticationSerializationFilter>
</mx:serializationFilter>
<mx:operationList>
<mx:HTTPOperation
name="getUser"
url="User/[ID]" />
</mx:operationList>
</mx:HTTPMultiService> import mx.rpc.AbstractOperation;
import mx.rpc.AsyncToken;
import mx.rpc.http.OAuthHeader;
import mx.rpc.utils.OAuthUtil;
import vo.User;
private function getUser(userId:uint):AsyncToken
{
var oauthData:OAuthHeader = new OAuthHeader();
oauthData.oauth_version = "1.0";
oauthData.oauth_consumer_key = "xvz1evFS4wEEPTGEFPHBog";
oauthData.oauth_token = "370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb";
oauthData.oauth_nonce = OAuthUtil.generateNonce();
oauthData.oauth_signature_method = OAuthHeader.SIGNATURE_METHOD_HMAC_SHA1;
oauthData.oauth_timestamp = OAuthUtil.getTimestamp();
var operation:AbstractOperation = service.getOperation("getUser");
operation.arguments = { ID: userId }; //replace URL tokens
oauthFilter.oauthData = oauthData;
return operation.send();
} La clase Static mx.utils.TypeUtil se puede utilizar para todos los tipos de piezas fundidas enumeradas anteriormente.
mx.rpc.OperationResponder se puede utilizar para hacer que los manejadores de operación sean más sencillos. Mimia la clase AsyncResponder de Flex, pero con una firma de funciones de resultados/fallas diferentes. Una firma de controlador de resultados válida es function(valueObject:Object):void . Una función de controlador de resultados recibirá el valor ResultEvent.result function(valueObject:MyResultClass):void Una firma de controlador de fallas válida es function(fault:Fault):void .
import mx.rpc.OperationResponder;
import vo.User;
private function getUser():void
{
service.getOperation("getUser").send().addResponder(new OperationResponder(onResult, onFault));
}
private function onResult(user:User):void
{
trace(user.firstName);
}
private function onFault(fault:Fault):void
{
trace(fault.faultDetail);
}