`

GWT Object Exporter ,GWT模块间传递对象

    博客分类:
  • gwt
阅读更多

 

GWT Object Exporter<o:p></o:p>

<o:p> </o:p>

1.        简介<o:p> </o:p>

GWT 允许传递的对象为Element,JavaScriptObject<o:p> </o:p>

GWT Object Exporter 提供将页面对象 导出(export) JavaScriptObject,将JavaScriptObject 导入(import)成代理对象(服务)

<o:p> </o:p>

2.        核心 & Demo<o:p></o:p>

interface IExportable          实现此接口的类将允许exporter javaScriptObject

interface IExportableExporter           exporter 接口,根据需要写出exportimport方法

<o:p> </o:p>

2.1   需要导出的类实现IExportable (或接口继承IExportable)<o:p></o:p>2.2 定义Exporter , 提供 导出/导入 IFace1接口方法<o:p></o:p>

java 代码
  1. interface IFace1  extends IExportable{   
  2.     void method1(String s1);   
  3. }   
  4.   
  5. class Face1 implements IFace1 {   
  6.        public void method1(String s1) {   
  7.            System.out.println("s1 = " + s1);   
  8.     }   
  9. }   

 

 

 

<o:p></o:p>

<o:p>

 

java 代码
  1. interface Exporter extends IExportableExporter {   
  2.   
  3.        public JavaScriptObject doExport(IFace1 iface1);   
  4.   
  5.        public IFace1 doImportIFace1(JavaScriptObject jso);   
  6. }   

 

2.3 应用

<o:p>java 代码</o:p><o:p> </o:p>

 

 

 

  1. public void onModuleLoad() {   
  2.   
  3.     Face1 face1 = new Face1();   
  4.   
  5.     Exporter exporter = (Exporter) GWT.create(Exporter.class);   
  6.   
  7.     JavaScriptObject jso = exporter.doExport(face1);   
  8.   
  9.     //其他模块中:先通过$wnd或其他方式获得此jso,后可导入   
  10.   IFace1 iface1 = exporter.doImportIFace1(jso);    
  11.   
  12.      iface1.method1();   
  13. }   

 

</o:p>

分享到:
评论
24 楼 kelvinlaw 2007-11-29  
謝謝樓主的耐心指點, 已經能成功互相share 了, 雖然必須在GWTSession 定義所有可能要放入map 的class 的put /get method, 有點不便, 但至少滿足了GWTSession 應有的功能

嘗試了一下, put 不用另行寫putA, 用原本的put(String key, Object value) 已經可以, 但必須用public Authentication getA(String key)取出

gwt-object-exporter 的出現比網絡上以serialize/deserialize 的方法去share object between widget , 無論在易用性, 效率, 和即時同步性都實在好太多!

仍然期待樓主的應用示範.
23 楼 yongyuan.jiang 2007-11-29  
session.putA(new Authentication ());

session.getA("key");
22 楼 yongyuan.jiang 2007-11-29  
ok了。

public class GWTSession implements IExportable {

HashMap map = new HashMap();

public Object putA(String key,Authentication value){
return map.put(key, value);
}

public Authentication getA(Object key) {
return (Authentication) map.get(key);
}
}

需要显示写出该类,exporter才会自动将他export和import.
21 楼 kelvinlaw 2007-11-29  
按照樓主的意思寫成
存入:
	gwtSession.put("objectTest", AuthenticationHelper.helper.doExport(auth));


取出:
	Window.alert("objectTest getCredential -> " + ((Authentication) AuthenticationHelper.helper.doImport((JavaScriptObject) GWTSessionAccessor.get().get("objectTest"))).getCredential());


這次也是ClassCastException, 但變成 JavaScriptObject
[ERROR] Unable to load module entry point class myFrameTest.inner.client.Inner (see associated exception for details)
java.lang.ClassCastException: com.google.gwt.core.client.JavaScriptObject cannot be cast to com.google.gwt.core.client.JavaScriptObject
	at myFrameTest.inner.client.Inner.onModuleLoad(Inner.java:27)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:342)
	at com.google.gwt.dev.shell.BrowserWidget.attachModuleSpace(BrowserWidget.java:326)
	at com.google.gwt.dev.shell.ie.BrowserWidgetIE6.access$200(BrowserWidgetIE6.java:36)
	at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.gwtOnLoad(BrowserWidgetIE6.java:70)
	at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.invoke(BrowserWidgetIE6.java:125)
	at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:293)


Orz...
20 楼 yongyuan.jiang 2007-11-29  
奇怪,我之前测试的class A implements IExportable不需要做这个操作。

怎么你那个还是出错?

发你的测试给我看看吧:
yongyuan.jiang@gmail.com
19 楼 yongyuan.jiang 2007-11-29  
呵呵,这个还是很基础的,等我把另外一个实际应用上传,包括对象间传输,事件的监听。

你先用这个了解了解也可以。呵呵
18 楼 yongyuan.jiang 2007-11-29  
oh!

sorry.

我知道问题所在了。

你需要这样:

setSession("auth",exporter.doExport(new Authentication()));

in inner:

Authentication auth = exporter.doImport(getSession("auth"))


只能传递JavaScriptObject!
17 楼 kelvinlaw 2007-11-29  
附上測試代碼, 請指教一下

內有2個widget, Outer 和Inner, Outer 內是一個frame, frame 內的Inner 的html, 測試的目的是想Outer 和Inner間可以通過GWTSession 而共用object.

但結果是, String 可以Share, 但自定的Object 就不行, 在get 出來會有 ClassCastException
[ERROR] Unable to load module entry point class myFrameTest.inner.client.Inner (see associated exception for details)
java.lang.ClassCastException: myFrameTest.commons.client.Authentication cannot be cast to myFrameTest.commons.client.Authentication
	at myFrameTest.inner.client.Inner.onModuleLoad(Inner.java:22)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:342)
	at com.google.gwt.dev.shell.BrowserWidget.attachModuleSpace(BrowserWidget.java:326)
	at com.google.gwt.dev.shell.ie.BrowserWidgetIE6.access$200(BrowserWidgetIE6.java:36)
	at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.gwtOnLoad(BrowserWidgetIE6.java:70)
	at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.invoke(BrowserWidgetIE6.java:125)
	at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:293)
16 楼 kelvinlaw 2007-11-28  
yongyuan.jiang 写道
commons.gwt.security.client.Authentication  也要继承IExportable

也是传递的对象嘛


唔, commons.gwt.security.client.Authentication 已經implements IExportable 了, 還是不行...

強調一下, ClassCastException 是當一個模块企圖去取出其他模块put 入GWTSession 的value 才會出現, 如果是自個模块put/get 是不會有問題的, 納悶...
15 楼 yongyuan.jiang 2007-11-28  
commons.gwt.security.client.Authentication  也要继承IExportable

也是传递的对象嘛
14 楼 kelvinlaw 2007-11-28  
yongyuan.jiang 写道
对了,我上传了新的
http://code.google.com/p/gwt-object-exporter/downloads/list

支持export内部类。

btw.
其实所以对象都能传递的,只是传递过去那个对象是否可以使用。
实现IExportable,就能将它拿来使用。

虽然能export对象出去,但是不建议复杂数据。如User能够export出去别的模块,但,假设user.getAddress是个list,list里面是个对象,暂时也没处理这个。


樓主的反應速度和熱心真今人感動...

剛下了最新的code

用了樓主提議的GWTSession 代碼

發現一個奇怪的問題, 我在第一個模块中, 创建GWTSession 並放入2 對 key/value, 分別是 "stringTest"/"String" 和 "objectTest"/Authentication, 在第二個模块中, 可以得知 map 的size = 2, 也可以順利取出 key為"stringTest" 的value, 但當嘗試取出"objectTest" 的value 時, GWT HostedMode 彈出異常
java.lang.ClassCastException: commons.gwt.security.client.Authentication cannot be cast to commons.gwt.security.client.Authentication


奇怪的是, 如果"stringTest"/"String" 和 "objectTest"/Authentication 2對 key/value 同樣是在第二個模块中寫入和讀出的話, 就可以順利讀取

請教一下
13 楼 yongyuan.jiang 2007-11-28  
对了,我上传了新的
http://code.google.com/p/gwt-object-exporter/downloads/list

支持export内部类。

btw.
其实所以对象都能传递的,只是传递过去那个对象是否可以使用。
实现IExportable,就能将它拿来使用。

虽然能export对象出去,但是不建议复杂数据。如User能够export出去别的模块,但,假设user.getAddress是个list,list里面是个对象,暂时也没处理这个。
12 楼 yongyuan.jiang 2007-11-28  
haha,原来是这样,按照你的方式,我试了一下,果然也不行,调试后,发现原因了,拿不到的原因是暂时不支持继承。

起初设计是考虑模块间接口调用,所以GWTSession继承HashMap没有做这方面处理。

不过,你可以这样实现:
public class GWTSession implements IExportable{

	HashMap map = new HashMap();
	
	public Object get(Object key) {
		return map.get(key);
	}

	public Object put(Object key, Object value) {
		return map.put(key, value);
	}

	public int size() {
		return map.size();
	}
}

之前不ok的原因是传递后的GWTSession实际上创建了新的HashMap.

ok,简单对象也是可以传递的,如下:

public class TestExportable implements EntryPoint{

	public void onModuleLoad() {
		
		exporter e = (exporter) GWT.create(exporter.class);
		
		GWTSession session = new GWTSession();
		session.put("auth", new A("auth"));
		session.put("2", new String("adf"));
		
		JavaScriptObject jso = e.export(session);
		
		GWTSession session2 = e.impor(jso);
		System.out.println(((A)session2.get("auth")).getN());

	}
	
	class A implements IExportable{
		String n;
		public A(String n2) {
			n = n2;// TODO Auto-generated constructor stub
		}
		public String getN(){
			return n;
		}
	}
	
	interface exporter extends IExporter{
		JavaScriptObject export(GWTSession session);
		GWTSession impor(JavaScriptObject jso);
	}

}

测试通过,A也要实现IExpotable.
11 楼 kelvinlaw 2007-11-28  
yongyuan.jiang 写道
是这样的,你在两个模块(两module,即有两个EntryPoint)都导入了GWTSession模块是吧。

如果都导入了GWTSession模块,那么在各自模块内都会创建两个GWTSession,所以里面的东西是空的。

所以只能导入一个GWTSession模块,独立于其他模块。


基于gwt object exporter,我们有个Hostpage模块,用于管理gwt object,以及页面组件,模块间事件处理,等有空了将一起发布出去。


先謝過你的回覆!

我的應用裡, 只有一個模块會创建GWTSession, 然後把GWTSession export 成jso 放在 html 中的javascript variable 中
	private static native void setGWTSession(JavaScriptObject gwtSession) /*-{
		$wnd.parent.gwtSession = gwtSession;
	}-*/;


另一個模块可以順利從html 的javascript 裡拿回GWTSession 的jso
	public static native JavaScriptObject getGwtSession() /*-{
		if ($wnd.parent.gwtSession == undefined) {
			return null;
		} else {
			return $wnd.parent.gwtSession
		}
	}-*/;


並import 成GWTSession
GWTSession gwtSession = helper.doImport(jso);


問題在於,在第一個模块put 入GWTSession 的key/value pair, 在第二個模块中拿不出黎, 全部是null

故嘗試把GWTSession 改成:
package commons.gwt.data.client;

import java.util.HashMap;

import com.macaufly.gwt.exporter.client.IExportable;

public class GWTSession extends HashMap implements IExportable {
	private Object object

	public Object getObject() {
		return object;
	}

	public void setObject(Object object) {
		this.object = object;
	}
}


第一個模块 setObject(new String("test")), 在第二個模块可以拿到"test", 是否exporter 對object 有一定要限制? 如必須為pojo, 因為我試過一個只有private constructor 的class 不能import/export.
10 楼 yongyuan.jiang 2007-11-28  
是这样的,你在两个模块(两module,即有两个EntryPoint)都导入了GWTSession模块是吧。

如果都导入了GWTSession模块,那么在各自模块内都会创建两个GWTSession,所以里面的东西是空的。

所以只能导入一个GWTSession模块,独立于其他模块。


基于gwt object exporter,我们有个Hostpage模块,用于管理gwt object,以及页面组件,模块间事件处理,等有空了将一起发布出去。
9 楼 kelvinlaw 2007-11-28  
我想寫一個GWTSession, 作用就如HTTPSession 一樣, 可以被同一個html 內的gwt widget 互相share object:

GWTSession:
package commons.gwt.data.client;

import java.util.HashMap;

import com.macaufly.gwt.exporter.client.IExportable;

public class GWTSession extends HashMap implements IExportable {
}


當然需要Helper 去import/export:
package commons.gwt.data.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.macaufly.gwt.exporter.client.IExporter;

public interface GWTSessionHelper extends IExporter {
	public JavaScriptObject doExport(GWTSession gwtSession);

	public GWTSession doImport(JavaScriptObject jso);
}


為了GWT Widget 可以方便拿到GWTSession來用, 寫了一個GWTSessionAccessor
package commons.gwt.data.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;

public class GWTSessionAccessor {

	private static GWTSessionHelper helper = (GWTSessionHelper) GWT
			.create(GWTSessionHelper.class);

	public static void clear() {
		setGWTSession(null);
	}

	private static native void setGWTSession(JavaScriptObject gwtSession) /*-{
		$wnd.parent.gwtSession = gwtSession;
	}-*/;

	public static native JavaScriptObject getGwtSession() /*-{
		if ($wnd.parent.gwtSession == undefined) {
			return null;
		} else {
			return $wnd.parent.gwtSession
		}
	}-*/;

	public static GWTSession get() {
		JavaScriptObject jso = getGwtSession();
		if (jso == null) {
			GWTSession gwtSession = new GWTSession();
			setGWTSession(helper.doExport(gwtSession));
			return gwtSession;
		} else {
			GWTSession gwtSession = helper.doImport(jso);
			return gwtSession;
		}
	}
}


實際應用:

	// put the auth into session
	GWTSession gwtSession = GWTSessionAccessor.get();
	gwtSession.put("auth", AuthenticationAccessor.get());

	// test the auth has been put into session
	gwtSession = GWTSessionAccessor.get();
	Authentication auth = gwtSession.get("auth");


發現 gwtSession 可以拿出來, 但內部的key/value pair 的數目是0...我用錯了嗎?....謝謝
8 楼 yongyuan.jiang 2007-11-23  
可以做到。

原理:
html里面内2个widget可以传递JavaScriptObject.
gwt object expoter就是提供将share的object解析成JavaScriptObject,和导入成类的。
7 楼 kelvinlaw 2007-11-22  
請問這個exporter的作用是什麼?
我想一個html 內有2個gwt 的widget, 2個widget 相互share 一個gwt 的object
可以做到嗎?
請指教
6 楼 yongyuan.jiang 2007-11-07  
o~,粗心大意了,你把错误的方法屏蔽就Ok拉,Download已经更新了~
5 楼 jayshow 2007-11-07  
还是少了点类呀~~?

相关推荐

Global site tag (gtag.js) - Google Analytics