Java与Flex学习笔记(6)----Java对象与ActionScript对象之间的序列化

      

     在学习了Java与Flex通信后,我们只是打通了Java与Flex通信的这条路。可是我们在Flex前端交互的信息是怎么传递给Java的呢?而Java为什么可以顺利的处理这些信息?这就是Java对象与ActionScript之间的序列化。Flex对象会被转化为Java兼容的类型,而Java类型也会被转化为ActionScrit兼容的类型。这样就保持了数据的一致性。

   

      参照官方文档,ActionScript中的类型会被转化成Java相兼容的如下类型:



ActionScript 类型 (AMF 3)

反序列化为 Java

支持的 Java 类型绑定

Array(密集)

java.util.List

java.util.Collection, Object[ ] (本机数组)

如果类型是一个接口,则会映射到下面的接口实现:

●  List 变为 ArrayList

●  SortedSet 变为 TreeSet

● Set 变为 HashSet

●  Collection 变为 ArrayList

自定义 Collection 实现的新实例会绑定到该类型。

Array(稀疏)

java.util.Map

java.util.Map

Boolean

字符串"true"或"false"

java.lang.Boolean

Boolean、boolean 和 String

flash.utils.ByteArray

byte []

 

flash.utils.IExternalizable

java.io.Externalizable

 

Date

java.util.Date

(已设置为协调世界时 (UTC) 格式)

java.util.Date、java.util.Calendar、java.sql.Timestamp、java.sql.Time 和 java.sql.Date

int/uint

java.lang.Integer

java.lang.Double、java.lang.Long、java.lang.Float、java.lang.Integer、java.lang.Short、java.lang.Byte、java.math.BigDecimal、java.math.BigInteger、String,以及基元类型 double、long、float、int、short 和 byte

null

null

基元

Number

java.lang.Double

java.lang.Double、java.lang.Long、java.lang.Float、java.lang.Integer、java.lang.Short、java.lang.Byte、java.math.BigDecimal、java.math.BigInteger、String、0(零)

如果发送了 null,则为基元类型 double、long、float、int、short 和 byte

Object(泛型)

java.util.Map

如果指定了 Map 接口,则为 java.util.Map 创建一个新的 java.util.HashMap,为 java.util.SortedMap 创建一个新的 java.util.TreeMap。

String

java.lang.String

java.lang.String、java.lang.Boolean、java.lang.Number、java.math.BigInteger、java.math.BigDecimal、char[]、以及任何基元数字类型

有类型对象

有类型对象

在使用 [RemoteClass] 元数据标签指定远程类名称时。Bean 类型必须具有公共的无参数构造函数。

有类型对象

undefined

null

null(对于对象)和默认值(对于基元)

XML

org.w3c.dom.Document

org.w3c.dom.Document

XMLDocument

(旧 XML 类型)

org.w3c.dom.Document

org.w3c.dom.Document

可以针对在 services-config.xml 文件中定义的任何通道启用对于 XMLDocument 类型的旧 XML 支持。此设置仅在将数据从服务器发回到客户端时很重要,它控制 org.w3c.dom.Document 实例如何发送到 ActionScript。有关更多信息,请参阅为通道配置 AMF 序列化

 

         而Java对象则会被反序列化为ActionScript相兼容的类型,详情请看如下所示列表:

 

Java 类型

ActionScript 类型 (AMF 3)

java.lang.String

String

java.lang.Boolean, boolean

Boolean

java.lang.Integer, int

int

如果值小于 0xF0000000 且大于 0x0FFFFFFF,则会按照 AMF 编码要求将值提升为 Number。

java.lang.Short, short

int

如果 i 小于 0xF0000000 且大于 0x0FFFFFFF,则会将值提升为 Number。

java.lang.Byte, byte[]

int

如果 i 小于 0xF0000000 且大于 0x0FFFFFFF,则会将值提升为 Number。

java.lang.Byte[]

flash.utils.ByteArray

java.lang.Double, double

Number

java.lang.Long, long

Number

java.lang.Float, float

Number

java.lang.Character, char

String

java.lang.Character[], char[]

String

java. math.BigInteger

String

java.math.BigDecimal

String

java.util.Calendar

Date

日期按照协调世界时 (UTC) 时区的时间进行发送。客户端和服务器必须根据时区相应地调整时间。

java.util.Date

Date

日期按照 UTC 时区的时间进行发送。客户端和服务器必须根据时区相应地调整时间。

java.util.Collection(例如,java.util.ArrayList)

mx.collections.ArrayCollection

java.lang.Object[]

Array

java.util.Map

Object(无类型)。例如,将 java.util.Map[] 转换为对象的 Array。

java.util.Dictionary

Object(无类型)

org.w3c.dom.Document

XML 对象

null

null

java.lang.Object(以前列出的类型除外)

有类型 Object

通过使用 JavaBean 内部检查规则将对象进行序列化,并且对象包括公共字段。不包括静态字段、瞬态字段、非公共字段,以及非公共 bean 属性或静态 bean 属性。

 

 

          下面通过一个注册的小例子来看看这个过程。


          新建一个model文件User.java,代码如下所示:



packagecom.ldfsoft.model;
 
importjava.io.Serializable;
importjava.util.List;
 
public classUser implements Serializable {
 
         private static final longserialVersionUID = 1L;
         private String username;
         private String passworld;
         private String confimPassworld;
         private String email;
         public String getUsername() {
                   return username;
         }
         public void setUsername(Stringusername) {
                   this.username = username;
         }
         public String getPassworld() {
                   return passworld;
         }
         public void setPassworld(Stringpassworld) {
                   this.passworld = passworld;
         }
         public String getConfimPassworld() {
                   return confimPassworld;
         }
         public void setConfimPassworld(StringconfimPassworld) {
                   this.confimPassworld =confimPassworld;
         }
         public String getEmail() {
                   return email;
         }
         public void setEmail(String email) {
                   this.email = email;
         }
        
        
 
}


        Flex提供了两个元素来帮助序列化。一个是RemoteClass,它是以[RemoteClass(alias="与Java相对应的类名")]形式写在ActionScript类前面。在这个ActionScript类中的属性名要与Java类中的属性名相同。另一个标记是Transient,他主要用于写在属性前表示此属性是瞬态变量,不参与序列化。


         请看下面这个ActionScript类文件User.as:


package ases
{
    import mx.collections.ArrayList;
    [Bindable]
    [RemoteClass(alias="com.ldfsoft.model.User")] 
    public class User
    {
       public var _username:String;
       public var _passworld:String;
       private var _confimPassworld:String;
       private var _email:String;
      
       public function User()
       {
       }
 
       public function get email():String
       {
           return _email;
       }
 
       public function set email(value:String):void
       {
           _email = value;
       }
 
       public function get confimPassworld():String
       {
           return _confimPassworld;
       }
 
       public function set confimPassworld(value:String):void
       {
           _confimPassworld = value;
       }
 
       public function get passworld():String
       {
           return _passworld;
       }
 
       public function set passworld(value:String):void
       {
           _passworld = value;
       }
 
       public function get username():String
       {
           return _username;
       }
 
       public function set username(value:String):void
       {
           _username = value;
       }
 
    }
}


 

    注意:由于Adobe Flash builder 4.5自动生成getter和setter时会将属性前加一个下划线“_”,这不影响序列化。


    新建一个service文件RegisterService.java,代码如下所示:


package com.ldfsoft.service;
 
import com.ldfsoft.model.User;
 
public class RegisterService{
    public User getRegisterMess(User user){
       System.out.println("用户名:"+user.getUsername());
       System.out.println("密码:"+user.getPassworld());
       System.out.println("Email:"+user.getEmail());
       return user;
    }
}


 

          在remoting-config.xml添加如下配置:


<destination id="registerMessage">
       <properties>
           <source>com.ldfsoft.service.RegisterService</source>
       </properties>
    </destination>


           新建一个Application文件RegisterApp.mxml,代码如下所示:


<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" >
   <fx:Script>	
	<![CDATA[
		import ases.RegisterEvent;
		import ases.User;
		
		import module.RegisterModule;
		
		import mx.controls.Alert;
		import mx.events.CloseEvent;
		import mx.events.FlexEvent;
		import mx.events.ResizeEvent;
		import mx.managers.PopUpManager;
		import mx.rpc.events.FaultEvent;
		import mx.rpc.events.ResultEvent;
		[Bindable]
		public var user:User=new User();
		import spark.components.Label;
		[Bindable]
		public var registerModule:RegisterModule=new RegisterModule();
		protected function submit_clickHandler(event:MouseEvent):void
		{
				// TODO Auto-generated method stub
				user.username=usernameMess.text;
				user.passworld=passworldMess.text;
				user.email=email.text;
				registerMessage.getRegisterMess(user);
				
		}
			
		protected function registerMessage_resultHandler(event:ResultEvent):void
		{
				// TODO Auto-generated method stub
				var user:User=event.result as User;
				Alert.show("username:"+user.username+"\npassworld:"+user.passworld+"\nEmail:"+user.email,"提示");
				
		}
			
		protected function registerMessage_faultHandler(event:FaultEvent):void
		{
				// TODO Auto-generated method stub
				Alert.show(event.fault.message as String,"提示");
		}
			
		
	]]>
	</fx:Script>
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
		<s:RemoteObject id="registerMessage" endpoint="../../messagebroker/amf" destination="registerMessage" result="registerMessage_resultHandler(event)" fault="registerMessage_faultHandler(event)" />
	</fx:Declarations>
	<s:Form width="100%" height="100%">
		<s:FormHeading  width="642" label="用户注册"/>
		<s:FormItem x="120" width="100%" label="用户名:" required="true" >
			<s:TextInput id="usernameMess" width="127"/>
		</s:FormItem>
		<s:FormItem width="100%"  label="密码:" required="true">
			<s:TextInput width="130" id="passworldMess"  displayAsPassword="true"/>
		</s:FormItem>
		<s:FormItem width="100%"  label="确认密码:" required="true">
			<s:TextInput width="132" id="confimPassworldMess"  displayAsPassword="true"/>
		</s:FormItem>
		<s:FormItem  width="461"  label="Email:" required="true">
			<s:TextInput width="133" id="email" />			
		</s:FormItem>
		<s:FormItem width="461" >
			<s:Button label="提交" id="submit" click="submit_clickHandler(event)"  useHandCursor="false" />
		</s:FormItem>
	</s:Form>
</s:Application>




        在这个文件中,我们先将User传递给Java,在后台打印出这些信息,然后又将这个被反序列化的Java对象返回给Flex前端。 


          打开服务器,运行RegisterApp.mxml,填入信息,界面如下所示:


Java与Flex学习笔记(6)----Java对象与ActionScript对象之间的序列化_第1张图片



         点击“提交”按钮,MyEclipse后台打印出如下所示信息:


Java与Flex学习笔记(6)----Java对象与ActionScript对象之间的序列化_第2张图片


        可见Flex发送过来的user对象已被序列化为Java相兼容的对象,前台也把Java后台返回来的信息展示出来了,如下所示:


Java与Flex学习笔记(6)----Java对象与ActionScript对象之间的序列化_第3张图片


         可见,ActionScript与Java正是因为序列化可以让他们能够“友好相处”,好了,今天就学习到这儿了。


         原创文章,转载请注明出处:http://www.dianfusoft.com/



你可能感兴趣的:(Java与Flex学习笔记(6)----Java对象与ActionScript对象之间的序列化)