Il existe plusieurs responsables de sérialisation personnalisés qui peuvent vous faciliter la vie (nécessite Flex 4).
Implémentation de modèle de conception composite pour les filtres de sérialisation HTTP . Remplacez l'une des 5 méthodes de SerializationFilter en utilisant différentes instances de filtre:
<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>Les méthodes de SerializationFilter qui peuvent être remplacées:
deserializeResultgetRequestContentTypeserializeParametersserializeBodyserializeURLLes méthodes qui ne sont pas remplacées sont manipulées à l'aide d'un fichier de sérialisation régulier.
Implémente serializeParameters , contentTypeProvider et serializeURL Méthodes.
Vous permet d'envoyer des verbes HTTP personnalisés, autres que Get ou Publier , qui n'est pas pris en charge par le lecteur Flash par défaut. Vous pouvez spécifier l'une des trois façons possibles de le faire:
methodOverride="header" ). N'oubliez pas de mettre à jour votre fichier Crossdomain.xml pour permettre à l'en-têtes d'être envoyée à d'autres domaines._method à toutes les URL ( methodOverride="url" )._method ( methodOverride="variable" ). Cela obligera votre demande à être sérialisée sous forme application/x-www-form-urlencoded .Ce filtre de sérialisation peut également être utilisé pour construire des URL dynamiques qui contiennent des paramètres tokenisés (enfermés entre crochets).
<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" });
} Implémente deserializeResult , contentTypeProvider et serializeBody Methods.
Sérialiser les demandes et désérialiser les réponses en JSON avec un analyseur JSON natif rapide (uniquement dans la version FP11; la version FP9 s'appuie sur JSON Parser d'As3Corelib). Les demandes et les réponses peuvent être converties à partir et en objets fortement typés à la volée. Les fonctionnalités de mappage d'objets suivantes sont disponibles:
ArrayElementType Metatag peut être utilisé pour cartographier les tableaux d'objets typés.Transient est respecté à la fois dans les demandes et les réponses./Date(1325376000000)/ peuvent être converties en objets Date , et vice versa. Par exemple, lorsque vous recevez ceci:
{
"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 vous avez un éventail d'objets…
[
{ "x":1, "y":5 },
{ "x":2, "y":4 },
{ "x":3, "y":3 },
{ "x":4, "y":2 },
{ "x":5, "y":1 }
]resultFormat="array" et resultElementType="{ElementClass}" . Par défaut, tous les tableaux sont enveloppés dans une ArrayCollection . Pour éviter ce comportement, définissez simplement makeObjectsBindable="false" sur l'instance d'opération. <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 est une implémentation d'un TypedSerializationFilter abstrait qui gère la transformation des types, tandis qu'une classe d'enfants concrète gère la sérialisation et la désérialisation des données réelles.
Le définition resultFormat sur toute autre valeur, en plus array et object (par défaut) entraînera un JSONSerializationFilter (ou tout autre TypedSerializationFilter ) à supprimer dans une HTTPOperation sélectionnée.
Implémente deserializeResult , contentTypeProvider et serializeBody Methods.
Agit de la même manière que le JSONSerializationFilter . Vous pouvez utiliser les propriétés xmlEncode et xmlDecode en option pour attribuer des méthodes de sérialisation personnalisées:
<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 };
} Étend le CompositeSerializationFilter avec deux nouvelles propriétés: username et password . Ajoutera un en-tête d'authentification HTTP de base à toutes les demandes.
<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> Étend le CompositeSerializationFilter . Peut être utilisé pour créer et affecter un en-tête OAuth à vos demandes.
<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 classe statique mx.utils.TypeUtil peut être utilisée pour tous les pièces moulées énumérées ci-dessus.
mx.rpc.OperationResponder peut être utilisé pour rendre les gestionnaires d'opération plus simples. Il imite la classe AsyncResponder de Flex, mais avec des signatures de fonctions de résultat / défaut différentes. Une signature de gestionnaire de résultats valide est function(valueObject:Object):void . Une fonction de gestionnaire de résultats recevra une valeur ResultEvent.result , vous pouvez donc simplement définir votre type de résultat dans un gestionnaire: function(valueObject:MyResultClass):void . Une signature de gestionnaire de défauts valide est 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);
}