在Google App Engine中使用Struts2框架

"GAE"(GoogleAppEngine)在早些时候发布了Java语言的支持,对广大的Java开发者来说,可以使用自己熟悉的语法来进行开发

,是很舒服的一件事情。Java世界中有大量已有的工具和框架,有一些是我们日常工作中就已经熟练使用的、而且广为流行的成熟

的,如果能够直接在GAE中使用,将大大提高我们的开发效率。

这几天利用Struts2,在GAE的Java版本支持环境中,写了个简单博客,现在将GAE+Struts2的组合经验,记录下来。

背景介绍

Python是一门有趣的语言,是作者第二个接触的动态脚本语言。第一个是大学时期做学生网站时期接触到Perl,后来工作后利

用Perl改写了公司的应用程序启动框架;几年后,由于Perl的语法实在是太过于羞涩难懂,便使用Python对启动框架进行了一次升

级。Python是面向对象的,同时也兼备了函数式编程的支持,另外,Python的语法强制缩进,非常容易读懂,因此Python版本的启

动框架对公司的Java开发者来说,也不难维护。

当然,这些都是题外话,GAE最先提供的是Python语言的支持,但是对我们Java开发者来说,要使用Python来进行大的应用开发

,还比较痛苦的一件事情。这时候GAE推出Java语言的支持,既是所有Java开发人员的福音,也是理所当然的一件事情,Google不可

能放弃目前企业应用开发领域里面最大的一股力量。

Struts2是目前应用最广泛的WEB开发框架,也是大部分的Java开发者最熟悉的开发框架,我们的GAE应用程序中,使用成熟的

Struts2可以减少很多额外的开发工作。

所需的Struts的库文件

目前Struts2的稳定版本是2.1.6,将下面的来自Struts-2.1.6的发行包的几个包,引入你的GAE项目工程中:

commons-fileupload-1.2.1.jareqpg2009-9-812:05

commons-io-1.3.2.jar

commons-logging-1.0.4.jar

commons-logging-api-1.1.jar

freemarker-2.3.13.jar

ognl-2.6.11.jar

struts2-core-2.1.6.jar

xwork-2.1.2.jar

如果你使用IDEA来创建项目,只要选择Struts的2.1.6版本的支持,IDEA会自动帮你引入所需要的库文件。

为AppEngine定制你的Struts

GAE里面的Servlet环境有一定的限制,不能使用线程(Thread),不能使用文件,还有别的一些要注意的地方。

首先,要加一个ServletContextListener的实现,在context初始化的时候,调用OgnlRuntime.setSecurityManager(null),让

Struts可以在GAE环境里面正常跑起来:

package your.servlet.pkg; 

 

import ognl.OgnlRuntime; 

 

import javax.servlet.ServletContextListener; 

import javax.servlet.ServletContextEvent; 

 

public class StrutsAppEngineAdapter implements ServletContextListener { 

public void contextInitialized(ServletContextEvent servletContextEvent) { 

OgnlRuntime.setSecurityManager(null); 

} 

 

public void contextDestroyed(ServletContextEvent servletContextEvent) { 

} 

} 

在web.xml中配置这个ServletContextListener的实例:

<web-app> 

 <listener> 

<listener-class>your.servlet.pkg.StrutsAppEngineAdapter</listener-class> 

 </listener> 

</web-app> eqpg2009-9-812:06

做完上面的工作之后,就可以在你的GAE里面使用Struts的功能了!

定制GAE的常用对象的Converter

Struts提供了Converter的机制,让你常用的业务对象可以直接在页面中显示,或者接受类型为业务对象的请求数据。GAE里面

常用的一些对象,定义了对应的Converter之后,可以是业务代码更加简洁。下面介绍两个常用对象的Converter的代码:

TextConverter,是针对com.google.appengine.api.datastore.Text对象的转换器,Text是GAE的存储中,大文本内容的保存对

象,在业务中很常用。先来看看TextConverter大的代码:

package your.servlet.pkg; 

 

import com.google.appengine.api.datastore.Text; 

import ognl.DefaultTypeConverter; 

 

import java.util.Map; 

 

public class TextConverter extends DefaultTypeConverter { 

@Override 

public Object convertValue(Map map, Object o, Class toType) { 

if (toType == Text.class) { 

String value = ((String[]) o)[0]; 

return new Text(value); 

} else if (toType == String.class) { 

Text text = (Text) o; 

return text.getValue(); 

} 

 

return null; 

} 

} 

TextConverter的作用主要是用于在WEB页面中,直接显示存储对象中的大文本内容。

另外一个是KeyConverter,是对com.google.appengine.api.datastore.Key对象的转换器,Key是GAE中三种主键(Long,

String,Key)的一种,在接收请求数据以及页面显示的时候,会经常用到。直接看代码:eqpg2009-9-812:06

package your.servlet.pkg; 

 

import com.google.appengine.api.datastore.Key; 

import com.google.appengine.api.datastore.KeyFactory; 

import ognl.DefaultTypeConverter; 

 

import java.util.Map; 

 

public class KeyConverter extends DefaultTypeConverter { 

@Override 

public Object convertValue(Map map, Object o, Class toType) { 

if (toType == Key.class) { 

String s = ((String[]) o)[0]; 

return KeyFactory.stringToKey(s); 

} else if (toType == String.class) { 

Key k = (Key) o; 

return KeyFactory.keyToString(k); 

} 

 

return null; 

} 

} 

在源代码的根目录,创建xwork-conversion.properties文件,内容如下:

com.google.appengine.api.datastore.Text=your.servlet.pkg.TextConverter 

com.google.appengine.api.datastore.Key=your.servlet.pkg.KeyConverter 

上面的工作都完成以后,就可以在你的Action里面直接使用Key类型的类变量,无需手工去做String和Key之间的转换!

ConventionPlugin不能使用

Struts2里面,最常用的Plugin应该是Convertion了,"零配置"即减少了写配置文件的麻烦,代码的组织结构看起来也清晰很多

但是在GAE里面,无法读取文件系统,目前的Convertion版本还无法正常工作,非常可惜。不过建议你的GAE应用中,Action和

JSP文件,还是按照ConvertionPlugin的组织方式来存放,一方面有利于后面的升级和迁移工作,另一方面也让你的应用的文件看

起来更清晰。

相关推荐