다음은 BlazeDS에서 기본적으로 지원되는 직렬화이다.
Serializing between ActionScript and Java
하지만 이런 기본 직렬화과정을 사용하지 않고 직렬화 자체를 커스터마이징(customizing)할 수 있다. 가령 클라이언트(예,Flash 애플리케이션)에서는 아이디, 이름, 속성, 가격의 정보가 중요하지만 서버(예,자바)에서는 재고(inventory)가 중요한 경우가 있다. 이런 경우에는 Flex와 Java쪽의 직렬화하는 클래스를 다음과 같이 디자인 할 수 있겠다.
01.// Product.as02.packagesamples.externalizable {03. 04.importflash.utils.IExternalizable;05.importflash.utils.IDataInput;06.importflash.utils.IDataOutput;07. 08.[RemoteClass(alias="samples.externalizable.Product")]09.publicclassProduct implementsIExternalizable {10. publicfunctionProduct(name:String=null) {11. this.name = name;12. }13. 14. publicvarid:int;15. publicvarname:String;16. publicvarproperties:Object;17. publicvarprice:Number;18. 19. publicfunctionreadExternal(input:IDataInput):void{20. name = input.readObject() asString;21. properties = input.readObject();22. price = input.readFloat();23. }24. 25. publicfunctionwriteExternal(output:IDataOutput):void{26. output.writeObject(name);27. output.writeObject(properties);28. output.writeFloat(price);29. }30.}31.}01.// Product.java02.packagesamples.externalizable;03. 04.importjava.io.Externalizable;05.importjava.io.IOException;06.importjava.io.ObjectInput;07.importjava.io.ObjectOutput;08.importjava.util.Map;09. 10./**11.* This Externalizable class requires that clients sending and 12.* receiving instances of this type adhere to the data format13.* required for serialization.14.*/15.publicclassProduct implementsExternalizable {16. privateString inventoryId;17. publicString name;18. publicMap properties;19. publicfloatprice;20. 21. publicProduct()22. {23. }24. 25. /**26. * Local identity used to track third party inventory. This property is27. * not sent to the client because it is server-specific.28. * The identity must start with an 'X'.29. */30. publicString getInventoryId() {31. returninventoryId;32. }33. 34. publicvoidsetInventoryId(String inventoryId) {35. if(inventoryId != null&& inventoryId.startsWith("X"))36. {37. this.inventoryId = inventoryId;38. }39. else40. {41. thrownewIllegalArgumentException("3rd party product42. inventory identities must start with 'X'");43. }44. }45. 46. /**47. * Deserializes the client state of an instance of ThirdPartyProxy48. * by reading in String for the name, a Map of properties49. * for the description, and 50. * a floating point integer (single precision) for the price. 51. */52. publicvoidreadExternal(ObjectInput in) throwsIOException,53. ClassNotFoundException {54. // Read in the server properties from the client representation.55. name = (String)in.readObject();56. properties = (Map)in.readObject();57. price = in.readFloat();58. setInventoryId(lookupInventoryId(name, price));59. }60. /**61. * Serializes the server state of an instance of ThirdPartyProxy62. * by sending a String for the name, a Map of properties63. * String for the description, and a floating point64. * integer (single precision) for the price. Notice that the inventory 65. * identifier is not sent to external clients.66. */67. publicvoidwriteExternal(ObjectOutput out) throwsIOException {68. // Write out the client properties from the server representation69. out.writeObject(name);70. out.writeObject(properties);71. out.writeFloat(price);72. }73. 74. privatestaticString lookupInventoryId(String name,floatprice) {75. String inventoryId = "X"+ name + Math.rint(price);76. returninventoryId;77. }78.}위 코드는 ActionScript의 flash.utils.IExternalizable 인터페이스와 Java의 java.io.Externalizable 인터페이스를 이용해 기본직렬화를 무시하고 이들 인터페이스에 정의된 readExternal와 writeExternal 메소드를 호출하여 직렬화 자체를 커스터마이징 할 수 있다는 것을 의미한다. Externalizable 인터페이스를 구현한 클래스에 정의된 메소드가 기본 직렬화보다 우선순위가 높다는 것을 기억하면 되겠다.
Flex의 ArrayCollection을 다시 한번 보기 바란다. 이 클래스는 flash.utils.IExternalizable를 구현했다.
mx.collections.ArrayCollection
꼭 이런 경우만은 아니다. 쓸데없는 데이터의 크기를 줄이기 위한 방법도 해당한다. 예를들어 ActionScript 코드를 보면 다음과 같다.
01.classExample implementsIExternalizable {02. 03. publicvarone:Boolean;04. publicvartwo:Boolean;05. publicvarthree:Boolean;06. publicvarfour:Boolean;07. publicvarfive:Boolean;08. publicvarsix:Boolean;09. publicvarseven:Boolean;10. publicvareight:Boolean;11. publicfunctionwriteExternal(output:IDataOutput) {12. varflag:int= 0;13. if(one) flag |= 1;14. if(two) flag |= 2;15. if(three) flag |= 4;16. if(four) flag |= 8;17. if(five) flag |= 16;18. if(six) flag |= 32;19. if(seven) flag |= 64;20. if(eight) flag |= 128;21. output.writeByte(flag);22. }23. publicfunctionreadExternal(input:IDataInput) {24. varflag:int= input.readByte();25. one = (flag & 1) != 0;26. two = (flag & 2) != 0;27. three = (flag & 4) != 0;28. four = (flag & 8) != 0;29. five = (flag & 16) != 0;30. six = (flag & 32) != 0;31. seven = (flag & 64) != 0;32. eight = (flag & 128) != 0;33. }34. }데이터 통신을 위해 쓸데없이 Boolean객체를 주고 받을 필요없다. 위 코드처럼 직렬화를 커스터마이징한다면 송수신 데이터 자체의 크기도 줄일 수 있다. 이는 매우 유용하다.
참고글
flash.utils.IExternalizable
커스텀 직렬화의 사용
ActionScript 3.0 데이터 유형 및 직렬화(serialization)
Serializing between ActionScript and Java
AMF 3 스팩
AS3 BitmapData AMF solution using IExternalizable
Flex and PHP: remoting with Zend AMF
글쓴이 : 지돌스타(http://blog.jidolstar.com/644)
댓글 없음:
댓글 쓰기