Coldfusion 8 и HTTP PUT - есть ли способ PUT объекта? - PullRequest
1 голос
/ 25 марта 2010

Мы используем EHCache с CF 8 для кэширования содержимого на центральном сервере с использованием интерфейса RESTful через HTTP. Я пытаюсь кэшировать cfquery объект на сервер кеша.

Я могу заставить это работать, если я вызываю EHCache напрямую (т.е. сохраняю его в локальном кэше), но если я пытаюсь кэшировать на удаленном сервере через HTTP, у меня возникают проблемы.

Код, который я использую, выглядит следующим образом:

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

CF не нравится эта ссылка на #ARGUMENTS.item# и он жалуется Complex object types cannot be converted to simple values.

Может кто-нибудь дать мне пример того, как поместить объект поверх http, используя CF? Если это невозможно с CF, то следующим примером будет Java-пример.

Большое спасибо заранее!

PS: я не хочу использовать сериализацию для текста / JSON и т. Д., Так как у этого подхода есть проблемы с целостностью данных и, что важнее всего, он недостаточно быстр.

Ответы [ 2 ]

3 голосов
/ 25 марта 2010

Да, вам придется сериализовать структуру аргументов, потому что невозможно передать двоичные объекты через HTTP без какой-либо формы сериализации. Как уже упоминалось, вы можете использовать JSON для сериализации объекта. Альтернативой JSON, которая также будет работать, является тег cfwddx, который может преобразовать объект в XML. Но JSON, вероятно, лучше, потому что он не такой подробный, как XML, сгенерированный cfwddx.

2 голосов
/ 26 марта 2010

Я понял, что могу использовать точный код выше, если сделаю следующее для переменной ARGUMENTS.item, прежде чем передать ее функции:

<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) />

Бинго! После этого serializedQuery будет использоваться, и он может быть PUT через провод по HTTP. Когда вы получите его обратно из EHCache, вам нужно будет сделать следующее:

<!--- 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#" />

Этот тип сериализации тоже очень, очень быстрый. Я могу понять других, используя представления JSON, но я не уверен, что они такие быстрые.

В любом случае, мне кажется, это отлично работает. Спасибо всем за ваш вклад. Я надеюсь, что другие найдут это полезным.

...