`
raymond.chen
  • 浏览: 1437184 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

如何在GWT中使用反射机制?

    博客分类:
  • GWT
阅读更多

在GWT中,Java的很多机制都是不支持的,比如:
      不支持类的动态加载
      不支持Java的反射机制
      不支持标准Java序列化
      不支持WEB模式下的Java对象清理
      不支持strictfp关键字,要避免在客户端代码中进行精确精度的计算
      ......

 

如果我们想让GWT支持反射机制,可以使用GWT Reflection框架扩展实现。以下简单介绍其实现步骤:

 

1、到http://gwtreflection.sourceforge.net/网站下载GWT Reflection框架文件,将ant.jar、antlr-2.7.7.jar、commons-cli-1.0.jar、gwtr-core.jar、gwtr-emule.jar、stringtemplate.jar这些jar文件拷贝到工程的lib目录下。

 

2、修改gwtr-emule.jar的JavaToJSArrayUtil.java源文件,将包含long和Long的代码段去掉,重新编译后覆盖gwtr-emule.jar里面对应的class文件和java文件。

      如果不这样做的话,在启动工程时会抛出以下异常信息:
           [ERROR] Errors in 'jar:file:/E:/gwtext/web/WEB-INF/lib/gwtr-emule.jar!/pl/rmalinowski/gwtreflect/client/utils/JavaToJSArrayUtil.java'
                  [ERROR] Line 90: Parameter 'value': type 'long' is not safe to access in JSNI code

 

      那是因为:
           在GWT1.5中,现在Java long类型可以正确的工作,允许你给一个64位的整数一个完全适当的范围。然而,由于JavaScript缺少真正的64位整型,long 被视为一对32位整型,使用JavaScript的标准数学符号不能很好的工作。

           如果你给JSNI传入一个long型值,GWT1.5编译器会产生错误,此时在你不完全需要long范围的地方,推荐方式是把类型改为double 。事实上,如果你使用long返回System.currentTimeMillis(),我们推荐你使用新建的Duration类来作为替换方式。对于JSNI 方法来说,它使用派生对象(opaque objects 不能进行任何数学计算)来处理long 值,你可以使用UnsafeNativeLong  annotation 来欺瞒编译器。但是我们强烈建议您避免这种方式,因为很容易忘掉JSNI方法中该值是一个非数值型的。 

 

 

     修改pl.rmalinowski.gwtreflect.tool.AntAttributeStrategy类的源码为:

public class AntAttributeStrategy implements ClassFindingStrategy {
	public boolean isClassReflectable(Class clazz) {
		Class[] classes = clazz.getInterfaces();
		if(classes!=null && classes.length>0){
			for(int i=0;i<classes.length;i++){
				if(classes[i].getSimpleName().equals("Reflectable")){
					return true;
				}
			}
		}
		return false;
	}
} 

    ,这样,只有实现了Reflectable接口的类才会生成其反射代理类。

 

 

3、如果要让一个类支持通过反射机制进行实例化,该类必须实现GWT Reflection框架中的Reflectable接口,其范例如下:

public class TicketRecievePanel extends BasePanel implements Reflectable{
	public TicketRecievePanel(){
		setTitle("票证领取:TicketRecievePanel");
		setClosable(true);
	}
	
	@Override
	public void onLoad() {
		MessageBox.setMinWidth(150);
		MessageBox.alert(this.getTitle());
	}
}

 

    通过反射实例化一个类的方法是:调用GWT Reflection框架中的Class类的forName方法。其范例如下:

String panelName = "com.cjm.client.ticket.TicketRecievePanel";
BasePanel panel = (BasePanel)pl.rmalinowski.gwtreflect.client.reflect.Class.forName(panelName).newInstance();

 

4、生成类的反射代理类和反射代理类的注册器类

     一个类在能够支持通过反射进行实例化之前,必须要用GWT Reflection框架提供的ant命令 GWTReflect 来生成该类的反射代理类和反射代理类的注册器类,然后调用注册器类的registerAll方法注册反射代理类之后,才能使反射机制生效。

     注册反射代理类的范例代码:

ClassRegistrator.registerAll();

 

     先注册反射代理类,再调用Class类的forName方法。

     在调用ant命令 GWTReflect 生成类的反射代理类之前,必须先将类打包成一个jar文件

 

    ant任务定义文件源码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--
	主要功能:
		1、清除之前生成的文件
		2、将类打包成jar文件
		3、生成反射代理类
		4、将反射代理类复制到java源码目录
-->
<project default="main" basedir=".">
	<property name="path.webinf" value="${basedir}/web/WEB-INF"/>

	<path id="lib.path">
		<fileset dir="${path.webinf}/lib" includes="*.jar"/>
	</path>
	
	<!-- 将类打包成jar文件 -->
	<target name="buildJar">
		<jar destfile="ticket.jar">
			<fileset dir="${basedir}/build/classes/">
            	<exclude name="com/cjm/client/gwtr/**"/> <!-- 排除反射代理类 -->
				<exclude name="com/cjm/public/**"/>
				<exclude name="com/cjm/server"/>
			</fileset>
		</jar>
	</target>

	<target name="clean">
		<delete file="${basedir}/ticket.jar"/>
		
		<!-- 删除java源码目录中的反射代理类 -->
		<delete dir="${basedir}/src/com/cjm/client/gwtr"/>

		<delete dir="${basedir}/gwtr_src"/>
		<mkdir dir="${basedir}/gwtr_src"/>
	</target>

	<!-- 用于生成反射代理类的task -->
	<taskdef name="gwtreflect" classname="pl.rmalinowski.gwtreflect.ant.GWTReflect" classpathref="lib.path" />
	
	<!--
		outdir:生成类的输出目录
		source:需要生成反射代理类的目标类的jar文件及其依赖jar文件
		packagein:目标类的包路径
		packageout:反射代理类的包路径
		templatepath:模板所在路径
	-->
	<target name="main" depends="clean,buildJar">
		<gwtreflect 
			outdir="${basedir}/gwtr_src" 
			source="${basedir}/ticket.jar;${path.webinf}/lib/gwtext.jar;${path.webinf}/lib/gwt-user.jar;${path.webinf}/lib/gwtr-core.jar;${path.webinf}/lib/gwtr-emule.jar" 
			packagein="com.cjm.client"
			packageout="com.cjm.client.gwtr"
			templatepath="${basedir}/st">
		</gwtreflect>
		
		<!-- 将反射代理类复制到java源码目录 -->
		<copy todir="${basedir}/src">
            <fileset dir="${basedir}/gwtr_src"/>
        </copy>
		
		<delete dir="${basedir}/gwtr_src"/>

	</target>
</project>

  

   对于范例中的TicketRecievePanel类,将生成以下两个Java类:

        TicketRecievePanel__GWTR    反射代理类

        ClassRegistrator   反射代理类的注册类。一个包下有一个注册类

 

5、需要在模块配置文件增加以下信息: 

<inherits name="pl.rmalinowski.gwtreflect.GWTReflect"/>

 

0
2
分享到:
评论
2 楼 脱了马甲的人 2013-09-02  
脱了马甲的人 写道
我照着例子一步一步配置,但是最后没成功,到了“生成反射代理类”这边,报
java.lang.IllegalArgumentException: Can't find template registrator.st。不知道怎么解决了。。
我用站内信发了更详细的内容给你,请帮忙看一看~~

已经好了
1 楼 脱了马甲的人 2013-09-02  
我照着例子一步一步配置,但是最后没成功,到了“生成反射代理类”这边,报
java.lang.IllegalArgumentException: Can't find template registrator.st。不知道怎么解决了。。
我用站内信发了更详细的内容给你,请帮忙看一看~~

相关推荐

    gwt反射 http://code.google.com/p/google-gin/wiki/GinTutorial

    标题中的“gwt反射”指的是Google Web Toolkit (GWT) 中的反射机制。GWT 是一个用于构建富互联网应用程序(RIA)的开放源代码Java框架,它允许开发者使用Java编程语言来编写前端应用,然后通过编译器将Java代码转换...

    GWT反射

    【标题】:“GWT反射”是指在Google Web Toolkit (GWT)环境中利用Java的反射机制来操作类和对象的一种技术。GWT是一个开源框架,它允许开发者使用Java语言编写客户端Web应用,然后编译成高效的JavaScript代码运行在...

    GWT开发手册.doc

    - **反射与垃圾回收**:GWT不支持Java的反射机制,以提高性能和减少复杂性。JavaScript引擎的单线程性质使得GWT中的`synchronized`关键字无效,同时没有垃圾回收机制,开发者需手动管理内存。 3. **运行时库支持**...

    GWT初学者手册

    5. **反射**:GWT不支持Java的反射机制,但提供GWT.getTypeName(Object)来获取对象的类名。 6. **无用对象清理**:JavaScript不支持垃圾回收,GWT无法在Web模式下清理JAVA对象。 7. **严格浮点运算**:GWT不支持...

    gwt 开发手册轻松入门gwt

    然而,某些特性在JavaScript中无法完全实现,如long类型被映射为double,多线程同步关键字`synchronized`仅作标记,反射机制受限,以及严格浮点运算不受支持。 2. **运行时库**:GWT模拟了Java运行时环境的一部分,...

    GWT开发者手册v2

    5. **反射与动态类型**:GWT不支持Java的反射机制,以提高效率和优化编译结果。`GWT.getTypeName(Object)`提供了一种获取对象类名的方法。 6. **无用对象清理**:JavaScript没有垃圾回收机制,因此GWT在Web模式下...

    GWT开发者手册

    - **反射**:GWT不支持Java的反射机制,但可以通过GWT.getTypeName(Object)获取对象的类名。 - **无用对象清理**:GWT不支持JavaScript的垃圾回收,因此开发者需要手动管理客户端对象。 - **浮点数处理**:GWT不...

    GWT开发者手册_v2

    - **序列化**:由于动态类装载和反射在编译后的 JavaScript 中不可用,GWT 不支持标准的 Java 序列化,而是提供了一个 RPC 机制,支持在调用远程方法时的自动对象序列化。 #### 二、构建用户界面 这部分涵盖了如何...

    GWT学习课件

    这使得开发者能够在开发过程中使用熟悉的Java语法和结构。 - **统一的编程模型**: GWT允许开发者使用Java编写客户端和服务器端代码,从而实现了语言层面的统一,便于代码复用和维护。 - **跨平台和兼容性**: 生成的...

    gwtbean:一个使用 JavaScriptObject 的概念,如 Spring BeanWrapper

    1. **Java Bean to JavaScriptObject 转换**:Gwt-Bean 提供了将 Java Bean 对象自动转换为 JavaScriptObject 的能力,使得 Java 对象可以直接在浏览器环境中使用。这大大简化了数据在服务器端和客户端之间传递的...

    GWT-Dagger2-Demo:带有 GWT 的 Google Dagger2 演示项目

    【GWT-Dagger2-Demo】是一个演示项目,它展示了如何在Google Web Toolkit(GWT)应用程序中集成和使用Dagger 2依赖注入框架。这个项目对于理解GWT与Dagger 2之间的协同工作方式非常有帮助,尤其对Java开发者来说,...

    GWTP-Typed-Slot-Upgrader

    此外,通过阅读源码,初学者也可以学习到关于GWTP框架、Maven插件开发以及Java反射机制的相关知识。 总的来说,GWTP-Typed-Slot-Upgrader是GWT和GWTP项目升级过程中的一个实用工具,它可以自动化处理TypedSlot的...

Global site tag (gtag.js) - Google Analytics