Hi everyone,
I am relatively new at Flex and am having writing a sample using the
IExternalizable interface. I have a Java object on the server side that
I want to send to the Flash player. I have searched through the older
posts on this group and on various other blog posts but not much help.
Here is the sample code: (sorry if it is a bit long)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> File: ResultObj.as
package
{
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;
[RemoteClass(alias="ResultObj")]
public class ResultObj implements IExternalizable
{
// number of records
public var m_numRecords:int;
// view name
public var m_viewName:String;
public function ResultObj()
{ }
public function readExternal (input:IDataInput):void
{
m_viewName = input.readObject();
m_numRecords = input.readInt();
}
public function writeExternal (output:IDataOutput):void
{
output.writeObject(m_viewName);
output.writeInt(m_numRecords);
}
}
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>> File: main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:RemoteObject id="ViewObj" destination="ViewRemoteObject">
<mx:method name="foo">
<mx:arguments>
<Arg1>
rowId
</Arg1>
<Arg2>
numRows
</Arg2>
</mx:arguments>
</mx:method>
<mx:method name="getResults">
<mx:arguments>
<Arg1>
accRowId
</Arg1>
<Arg2>
numRows
</Arg2>
</mx:arguments>
</mx:method>
</mx:RemoteObject>
<mx:Script>
<![CDATA[
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.events.ResultEvent;
import ResultObj;
// create a compile time dependency on ResultObj class
private static const REG:* =
registerClassAlias("ResultObj",ResultObj);
private var m_ResultObj:ResultObj;
private function getList(event:Event):void {
ViewObj.addEventListener(ResultEvent.RESULT,
displayResponse);
ViewObj.addEventListener(FaultEvent.FAULT, displayFault);
ViewObj.getResults(AccountId.text, 1);
registerClassAlias("ResultObj", ResultObj);
}
private function displayResponse(resEvt:ResultEvent):void {
Alert.show("displayReponse called, " + resEvt.toString());
m_ResultObj = resEvt.result as ResultObj;
}
private function displayFault(resEvt:Event):void {
Alert.show("displayFault called, " + resEvt.toString());
}
]]>
</mx:Script>
<mx:WipeLeft id="myWL" duration="500"/>
<mx:Panel width="617" height="608" layout="absolute" left="10"
top="10" title="Account Detail" id="AcctOptView">
<mx:VDividedBox x="10" y="0" height="480" width="577">
<mx:Canvas label="AccountsCanvas" width="100%" height="100%"
backgroundColor="#FFFFCC">
<mx:Form x="10" y="10" width="557" height="215" >
<mx:FormHeading label="Enter Account Details"
width="304" />
<mx:FormItem label="Account Name">
<mx:TextInput id="AccountName" width="200"
text=""/>
</mx:FormItem>
<mx:FormItem label="Account Id">
<mx:TextInput id="AccountId" width="100"/>
</mx:FormItem>
<mx:FormItem label="Primary Contact">
<mx:TextInput id="PrimaryContact" width="200" />
</mx:FormItem>
<mx:Button label="GetAccounts"
click="getList(event)" id="GetAccounts"/>
</mx:Form>
</mx:Canvas>
<mx:Canvas label="Canvas 1" width="100%" height="100%"
backgroundColor="#FFFFCC">
</mx:Canvas>
</mx:VDividedBox>
</mx:Panel>
</mx:Application>
And I have the following in the remoting-config.xml
<destination id="ViewRemoteObject">
<properties>
<source>MyView</source>
</properties>
</destination>
On the Java side I have following source code:
>>>>>>>>>>>>>>>>>>>>>>>>>>>MyView.java
public class MyView {
public MyView () {
}
public ResultObj getResults (String viewName, int numRecords) {
ResultObj res = new ResultObj ();
return (res);
}
}
>>>>>>>>>>>>>>>>>>>>>>>>>>> ResultObj.java
public class ResultObj implements Externalizable {
private String m_viewName;
private Integer m_numRecords;
public ResultObj() {
m_numRecords = new Integer (0);
m_viewName = new String ("Dummy Default View");
}
/*
* (non-Javadoc)
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
*/
public void readExternal (ObjectInput in)
throws IOException, ClassNotFoundException
{
m_viewName = (String) in.readObject();
m_numRecords = in.readInt();
}
/*
* (non-Javadoc)
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
*
* Serializes the server state of an instance of ResultObj
* to the AMF client (Flash in the browser)
*/
public void writeExternal (ObjectOutput out) throws IOException {
System.err.println("[ResultObj::writeExternal]");
out.writeObject(m_viewName);
out.writeInt(m_numRecords);
System.err.println("Completed [ResultObj::writeExternal]");
}
}
Both the Java files are compiled and put under
D:\lcds\jrun4\servers\default\flex\WEB-INF\classes. I debugged this more
and the method MyView::getResults is being invoked and the method
ResultObj::writeExternal also gets invoked successfully but on the
browser side I get the following error
ArgumentError: Error #2004: One of the parameters is invalid.
And then I get the following error:
displayFault called, [FaultEvent fault=[RPC Fault faultString="Didn't
receive an acknowledge message" faultCode="Server.Acknowledge.Failed"
faultDetail="Was expecting mx.messaging.messages.AcknowledgeMessage, but
received null"] messageId="CEE768B6-6010-738A-C432-5C83918438BE"
type="fault" bubbles=false cancelable=true eventPhase=2]
So I am guessing the browser side doesn't know to construct the object
ResultObj.as. If anyone can shed some light on how to fix it that would
be very much appreciated.
Many thanks,
Ash