麻雀虽小,五脏俱全:上手Google App Engine遇到的问题总结
麻雀虽小,五脏俱全系列
---
虽然经常见到云计算的相关新闻,而且在CSDN的论坛里也解答过关于Google App Engine持久化方面的问题,但并没有将这两者联系起来。我一直以为GAE是一个类似于Spring或者Hibernate一样的开源项目罢了。最近构思技术族谱这个开源项目的时候,想先找一个免费的jsp空间做做前期测试,竟然发现GAE就是Google的云计算平台,其提供的免费流量和计算能力还是相当可观的,这对我来说,无疑是天上掉下一块大馅饼。
使用Google提供的Eclipse插件,开发还是很便利的,跟写普通的JAVA web程序也没有太大的差异,不过随插件提供的本地模拟环境还是和部署后的真实环境有些差异,从开始做,到真正把一个最简单的功能(Echo)成功上线,大概花费了三天的业余时间,并遇到了几个小问题,在这里总结一下,希望对大家有用。
我的GAE版本:1.2.2
第一点,算是个注意事项吧。
GAE的插件在每次打包时,会自动清理WEB-INF/classes目录,所以struts.xml,log4j.properties等配置文件无法直接放在该目录里,可以放在src目录,或者可以再建一个独立的目录,比如cfg存放配置文件,并将该目录加为class目录即可。
第二点,JSTL标签默认无法使用(不报错,也不被解析)。
需要在jsp页面的page direction中增加isELIgnored="false",比如:
<%@ page contentType="text/html; charset=UTF-8" language="java" pageEncoding="UTF-8" isELIgnored="false"%>
官方说这可能跟他们使用的Jasper版本有关,也许在下一次升级的时候会改进。参见:http://groups.google.com/group/google-appengine-java/msg/da389df15e056697?hl=en
第三点,中文问题。
在windows上开发,默认文件编码是GBK,这时候如果JSP页面也将encoding设置为GBK的话,通常需要增加Filter来实现编码转换来消除乱码。我把整个项目全部改成UTF-8,也就是文件编码UTF-8,而且jsp中指定的charset也是UTF-8,中文问题可以自然解决(不用增加额外的filter)。
第四点,整合了Struts2,但默认情况下,由于ONGL权限导致部署后的应用访问失败。
这个问题在本地测试不会出现,但部署上去就会抛出如下异常:
错误信息:
08-31 08:37AM 19.209 /xxxxxxx.action?fromUrlEncode=%E7%BC%96%E7%A0%81&fromUrlNonEncode=%E6%9C%AA%E7%BC%96%E7%A0%81 404 86ms 158cpu_ms 0kb Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729),gzip(gfe)
See details
117.79.68.140 - - [31/Aug/2009:08:37:19 -0700] "POST /xxxxxxxx.action?fromUrlEncode=%E7%BC%96%E7%A0%81&fromUrlNonEncode=%E6%9C%AA%E7%BC%96%E7%A0%81 HTTP/1.1" 404 0 "http://jszupu.appspot.com/xxxxxxx.jsp" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729),gzip(gfe)" "jszupu.appspot.com"
官方说是因为实际运行环境的安全设置和插件带的模拟环境不太一样,并给出了一个解决方案,需要增加一个Listener,listener内容如下:
1. public class OnglPermissionListener implements ServletContextListener{ 2. public OnglPermissionListener() { 3. } 4. 5. public void contextInitialized(ServletContextEvent sce) { 6. OgnlRuntime.setSecurityManager(null); 7. } 8. 9. public void contextDestroyed(ServletContextEvent arg0) { 10. } 11. 12. }