2010-03-25 4 views
1

Nous utilisons EHCache avec CF 8 pour mettre en cache des éléments sur un serveur central en utilisant une interface RESTful sur HTTP. Je suis en train de mettre en cache un objet cfquery sur le serveur de cache.Coldfusion 8 et HTTP PUT - existe-t-il un moyen de mettre un objet en place?

Je peux obtenir que cela fonctionne si j'appelle EHCache direct (à savoir le stocker dans un cache local) mais si j'essaie de mettre en cache sur un serveur distant via HTTP, je rencontre des problèmes.

Le code que je utilise est la suivante:

<cfhttp url="http://localhost:8080/myCache/myKey" 
    method="put" 
    result="r" 
    timeout="2" 
    throwonerror="true" > 
    <cfhttpparam type="body" value="#ARGUMENTS.item#" /> 
</cfhttp> 

CF n'aime pas cette référence à #ARGUMENTS.item# et il se plaint Complex object types cannot be converted to simple values.

Quelqu'un peut-il me donner un exemple de la façon de mettre un objet sur http en utilisant CF? Si cela n'est pas possible avec CF alors un exemple de Java serait la meilleure chose suivante.

Merci beaucoup d'avance! PS: Je ne veux pas utiliser la sérialisation vers du texte/JSON, etc. car cette approche pose des problèmes d'intégrité des données et surtout, elle n'est pas assez rapide.

+0

Pouvez-vous passer à CF9? Il a construit des crochets d'ehcache. – kevink

+2

La valeur passée dans cfhttpparam/valeur DOIT être une chaîne - texte ou binaire. Vous allez devoir sérialiser arguments.item d'une certaine façon. –

+0

@kevink - CF9 permet uniquement la mise en cache sur le système local, pas sur un serveur cache central AFAIK. Nous utilisons un environnement en cluster. –

Répondre

2

Je compris que je peux utiliser le code exact ci-dessus si je fais ce qui suit à la variable ARGUMENTS.item avant que je passe à la fonction:

<cfquery name="qData" datasource="#VARIABLES.dsn#"> 
select * from myData 
</cfquery> 

<!--- Setup and init Java objects ---> 
<cfset byteArrayOutputStream = createObject("java","java.io.ByteArrayOutputStream") /> 
<cfset objectOutputStream = createObject("java","java.io.ObjectOutputStream") /> 
<cfset byteArrayOutputStream.init() /> 
<cfset objectOutputStream.init(byteArrayOutputStream) /> 

<!--- Serialize the cfquery object ---> 
<cfset objectOutputStream.writeObject(qData) /> 
<cfset serializedQuery = toBase64(byteArrayOutputStream.toByteArray()) /> 
<cfset objectOutputStream.close() />  

<!--- Stick in the cache ---> 
<cfset myCache.put(myCacheName, key, serializedQuery) /> 

Bingo! Après que serializedQuery est là pour être utilisé et il peut être PUT à travers le fil via HTTP. Lorsque vous récupérerez de EHCache, vous devez le faire ce qui suit:

<!--- Get result value from cache ---> 
<cfset cacheData = myCache.get(myCacheName, key) /> 

<!--- Java objects setup ---> 
<cfset byteArrayInputStream = createObject("java","java.io.ByteArrayInputStream") /> 
<cfset objectInputStream = createObject("java","java.io.ObjectInputStream") /> 

<!--- deserialize ---> 
<cfset ba = toBinary(cacheData) /> 
<cfset byteArrayInputStream.init(ba) /> 
<cfset objectInputStream.init(byteArrayInputStream) /> 
<cfset deserializedQuery = objectInputStream.readObject() /> 
<cfset objectInputStream.close() /> 

<!--- Dump query ---> 
<cfdump var="#deserializedQuery#" /> 

Ce type de sérialisation est très, très rapide aussi. Je peux comprendre les autres en utilisant des représentations JSON mais je ne suis pas sûr qu'ils soient aussi rapides.

De toute façon, cela semble fonctionner très bien pour moi. Merci à tous pour votre participation. J'espère que les autres trouvent cela utile.

3

Oui, vous devrez sérialiser la structure des arguments car il n'y a aucun moyen de passer des objets binaires via HTTP sans une certaine forme de sérialisation. Comme cela a déjà été mentionné, vous pouvez utiliser JSON pour sérialiser l'objet. Une alternative à JSON qui fonctionnerait également est la balise cfwddx qui peut convertir l'objet en XML. Mais JSON est probablement meilleur car il n'est pas aussi détaillé que le XML généré par cfwddx.

Questions connexes