다음은 BlazeDS에서 기본적으로 지원되는 직렬화이다.
Serializing between ActionScript and Java
하지만 이런 기본 직렬화과정을 사용하지 않고 직렬화 자체를 커스터마이징(customizing)할 수 있다. 가령 클라이언트(예,Flash 애플리케이션)에서는 아이디, 이름, 속성, 가격의 정보가 중요하지만 서버(예,자바)에서는 재고(inventory)가 중요한 경우가 있다. 이런 경우에는 Flex와 Java쪽의 직렬화하는 클래스를 다음과 같이 디자인 할 수 있겠다.
01.
// Product.as
02.
package
samples.externalizable {
03.
04.
import
flash.utils.IExternalizable;
05.
import
flash.utils.IDataInput;
06.
import
flash.utils.IDataOutput;
07.
08.
[RemoteClass(alias=
"samples.externalizable.Product"
)]
09.
public
class
Product
implements
IExternalizable {
10.
public
function
Product(name:
String
=
null
) {
11.
this
.name = name;
12.
}
13.
14.
public
var
id:
int
;
15.
public
var
name:
String
;
16.
public
var
properties:
Object
;
17.
public
var
price:
Number
;
18.
19.
public
function
readExternal(input:IDataInput):
void
{
20.
name = input.readObject()
as
String
;
21.
properties = input.readObject();
22.
price = input.readFloat();
23.
}
24.
25.
public
function
writeExternal(output:IDataOutput):
void
{
26.
output.writeObject(name);
27.
output.writeObject(properties);
28.
output.writeFloat(price);
29.
}
30.
}
31.
}
01.
// Product.java
02.
package
samples.externalizable;
03.
04.
import
java.io.Externalizable;
05.
import
java.io.IOException;
06.
import
java.io.ObjectInput;
07.
import
java.io.ObjectOutput;
08.
import
java.util.Map;
09.
10.
/**
11.
* This Externalizable class requires that clients sending and
12.
* receiving instances of this type adhere to the data format
13.
* required for serialization.
14.
*/
15.
public
class
Product
implements
Externalizable {
16.
private
String inventoryId;
17.
public
String name;
18.
public
Map properties;
19.
public
float
price;
20.
21.
public
Product()
22.
{
23.
}
24.
25.
/**
26.
* Local identity used to track third party inventory. This property is
27.
* not sent to the client because it is server-specific.
28.
* The identity must start with an 'X'.
29.
*/
30.
public
String getInventoryId() {
31.
return
inventoryId;
32.
}
33.
34.
public
void
setInventoryId(String inventoryId) {
35.
if
(inventoryId !=
null
&& inventoryId.startsWith(
"X"
))
36.
{
37.
this
.inventoryId = inventoryId;
38.
}
39.
else
40.
{
41.
throw
new
IllegalArgumentException("3rd party product
42.
inventory identities must start with
'X'
");
43.
}
44.
}
45.
46.
/**
47.
* Deserializes the client state of an instance of ThirdPartyProxy
48.
* by reading in String for the name, a Map of properties
49.
* for the description, and
50.
* a floating point integer (single precision) for the price.
51.
*/
52.
public
void
readExternal(ObjectInput in)
throws
IOException,
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 ThirdPartyProxy
62.
* by sending a String for the name, a Map of properties
63.
* String for the description, and a floating point
64.
* integer (single precision) for the price. Notice that the inventory
65.
* identifier is not sent to external clients.
66.
*/
67.
public
void
writeExternal(ObjectOutput out)
throws
IOException {
68.
// Write out the client properties from the server representation
69.
out.writeObject(name);
70.
out.writeObject(properties);
71.
out.writeFloat(price);
72.
}
73.
74.
private
static
String lookupInventoryId(String name,
float
price) {
75.
String inventoryId =
"X"
+ name + Math.rint(price);
76.
return
inventoryId;
77.
}
78.
}
위 코드는 ActionScript의 flash.utils.IExternalizable 인터페이스와 Java의 java.io.Externalizable 인터페이스를 이용해 기본직렬화를 무시하고 이들 인터페이스에 정의된 readExternal와 writeExternal 메소드를 호출하여 직렬화 자체를 커스터마이징 할 수 있다는 것을 의미한다. Externalizable 인터페이스를 구현한 클래스에 정의된 메소드가 기본 직렬화보다 우선순위가 높다는 것을 기억하면 되겠다.
Flex의 ArrayCollection을 다시 한번 보기 바란다. 이 클래스는 flash.utils.IExternalizable를 구현했다.
mx.collections.ArrayCollection
꼭 이런 경우만은 아니다. 쓸데없는 데이터의 크기를 줄이기 위한 방법도 해당한다. 예를들어 ActionScript 코드를 보면 다음과 같다.
01.
class
Example
implements
IExternalizable {
02.
03.
public
var
one:
Boolean
;
04.
public
var
two:
Boolean
;
05.
public
var
three:
Boolean
;
06.
public
var
four:
Boolean
;
07.
public
var
five:
Boolean
;
08.
public
var
six:
Boolean
;
09.
public
var
seven:
Boolean
;
10.
public
var
eight:
Boolean
;
11.
public
function
writeExternal(output:IDataOutput) {
12.
var
flag:
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.
public
function
readExternal(input:IDataInput) {
24.
var
flag:
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)
댓글 없음:
댓글 쓰기