截止到今天下午,中午把自己的应用部署到了Google app engine,用了一周的时间啊,真是费劲周折
好长时间了,听说Google出了个
Google App Engine - Google Code,说是可以让用户上传自己的应用,但是只支持python,当时就想什么
时候支持java啦啊,上个月看新闻就听说Google app engine 要开始支持java啦,哈哈,喜,到时候把我的写的blog传上去,哈哈
上周,终于知道了Google app engine终于开始宣布支持java了,哈哈呼呼,动手,到官网一看,没有支持java的动静啊,
对,英文页面,哈哈,看来中文的还是慢一拍啊
首先到注册一个,竟然还要手机号发注册码,Google了一下 说在手机号前加 86就OK了,填上手机号点按钮,呦,短信马
上就来啦,搞定,注册成功。
这下下载SDK,还有eclipse插件,帮助文档只有英文的,配合Google工具栏的翻译功能,基本能看懂,哈哈,感觉一路下
来,英语水平有所上升啊,哈哈
打开eclipse,装上插件,很轻松的建了第一个应用,插件自动生成了一个小实例,部署上去,惊叹于Google的GWT
开始一直我原来写的blog程序,原来到处找免费的空间,jsp的空间不好找,先是找了
http://www.eatj.com/,但是没24小
时(好像是)就会自动停止,必须手动重启服务,原来还坚持去上去看看,后来终于因为有一次很忙时间太长被注销了,接下来就听
说了
http://www.stax.net/,跟Google的路子差不多,好像还更自定义些,继续使用着,搞java朋友可以去看看
因为google app engine使用Google Account,原来的用户管理模块需要剔除,原来数据库使用的是mysql hibernate,现在
Google 使用JDO,数据库被封装了,还好,当初设计是采用了工厂模式,实现了数据库访问模块与业务处理模块的松耦合,很容易
配置数据库访问模块的更改,感受到好的设计真是为以后修改省很多事啊。
接着说部署我的Google app engine,终于改好相关代码,准备上传了,噩梦开始了
1、Unable to upload:
java.lang.IllegalStateException: cannot find javac executable based on java.home, tried “D:\Java\jdk1.6.0_13
\jre\bin\javac.exe” and “D:\Java\bin\javac.exe”
参考http://zhuyx808.javaeye.com/blog/370124
http://onlypython.group.javaeye.com/group/blog/366471
http://618119.com/archives/2009/04/12/148.html
2、决定转战Linux..
手上有四个版本的Linux,Ubuntu,Redhat,Fedora,openSUSE,都装过,后来感觉还是Fedora比较好用,我装的是
Fedora9,Fedora10正在下载中
以下Linux安装配置,仅限于在Fedora9上安装通过,资料都是通过Google搜索得来,感谢各位网友,网络的力量真是强大。
1、在VMware中装上Fedora9后,首先安装VMware-tools,方便与主机交互
首先需要下载相应的kernel-devel.rpm包进行安装
首先查看内核版本:uname -r一下,我的是2.6.25-14.fc9.i686,
所以下载kernel-devel-2.6.25-14.fc9.i686.rpm,然后运行rpm -ivh kernel-devel-2.6.25-14.fc9.i686.rpm 进行安装. 内核安
装完毕后,需要用这个命令确定内核 C header 的安装目录:ls -d /usr/src/kernels/$(uname -r)*/include
安装内核具体步骤如下:
[root@localhost ~]# uname -r
2.6.25-14.fc9.i686
[root@localhost ~]# rpm -q kernel-devel
package kernel-devel is not installed
[root@localhost ~]# cd /home
[root@localhost home]# wget ftp://rpmfind.net/linux/fedora/releases/9/Everything/i386/os/Packages/kernel-devel-
2.6.25-14.fc9.i686.rpm
[root@localhost home]# rpm -i kernel-devel-2.6.25-14.fc9.i686.rpm
[root@localhost home]# rpm -q kernel-devel
kernel-devel-2.6.25-14.fc9.i686
再安装gcc,否则安装VMware-tools时会提示:Setup is unable to find the "gcc" program on your machine. Please make
sure it
is installed. Do you want to specify the location of this program by hand?
[yes]
What is the location of the "gcc" program on your machine?
在命令行执行:yum install gcc
然后安装VMware Tools就行了,打开菜单“VM -> Install VMware Tools”,然后有光盘自动弹出,把里面的源代码拷贝出来.我的文
件是VMwareTools-6.5.0-xxxxx.tar.gz,我把它拷贝到/opt里.
安装 VMware TOOLS
cd /opt
tar -zxvf VMwareTools-6.5.0-xxxxx.tar.gz
cd vmware-tools-distrib/
./vmware-install.pl
再一路安回车OK
2、由于在装载xorg-x11-drv-vmmouse驱动时的一个bug,在客户虚拟机的显示中,鼠标位置可能不正确。直到被更新前,在客户机
中添加Option NoAutoAddDevices到/etc/X11/xorg.conf文件的ServerFlags节中。如果需要,创建这个节:
Section "ServerFlags"
Option "NoAutoAddDevices"
EndSection
3、第一,安装JDK
第一,到http://java.sun.com下载最新JDK,当前本人下载的是jdk1.6.0_02!下载文件:jdk-6u2-linux-i586-rpm.bin.注意是
rpm.bin的!
第二,给下载回来的文件增加执行权限:chmod 755 jdk-6u2-linux-i586-rpm.bin.
第三,执行文件:./jdk-6u2-linux-i586-rpm.bin.
第四,执行文件产生一个rpm文件,可直接双击执行也可以在shell下执行:rpm -ivh jdk-6u2-linux-i586-rpm.
第五:配置环境变量,环境变量配置可在全局文件/etc/profile下修改,这样所有linux系统的用户都可以用JDK,如果只是特定的
用户用可修改/root/.bashrc文件,本人的修改为:
#java set
set JAVA_HOME=/usr/java/jdk1.6.0_02
export JAVA_HOME
export JRE_HOME=/usr/java/jre1.6.0_02
set JAVA_BIN=/usr/java/jre1.6.0_02
export JAVA_BIN
第五,当环境变量修改完后,重起系统,在shell下输入java,看是否输入相关JAVA帮助信息,如果有,说明已经安装成功!如果没有,
检查一下变量环境设置是否有误!
2,安装Eclipse,Eclipse不需要安装,只要解压缩就行了
运行Google app Engine不需要Tomcat
3,安装tomcat的方法跟安装eclipse的一样,也是下一个tar.gz的文件按安装eclipse方法和步骤就行了!进入tomcat/bin
下./startup.sh,如果在shell出现jdk的相关信息说明已经安装成功启动了,在firefox下打http://localhost:8080/出现tomcat页就
大成功了!
在以上的安装过程之中,出现了小插曲,就是tomcat找不到JDK,后来我又到JAVA网站下了一个JRE回来安装,并建JRE_HOME,重起
TOMCAT,成功了!
4、运行Google App Engine的应用,提示
** Unable to load Mozilla for hosted mode **
java.lang.UnsatisfiedLinkError:
/home/dhofmann/development/ide/gwt-linux-1.4.61/mozilla-1.7.12/libxpcom.so:
libstdc++.so.5: cannot open shared object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
解决办法:
Search for stdc++5 in synaptic package manager (System->Administration->Synaptic) and then mark and install it. Or
use this console command:
yum install libstdc++.so.5
停止进程命令:
就是kill 比较不错,如果kill不了. 加上-9
如#kill -9 1778
注1778 为进程pid
pid可以通过ps aux|grep 服务名查得
启动Eclipse时,提示错误:
eclipse.buildId=M20090211-1700
java.version=1.6.0
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=linux, ARCH=x86, WS=gtk, NL=zh_CN
Command-line arguments: -os linux -ws gtk -arch x86
!ENTRY org.eclipse.ui.workbench 4 0 2009-04-18 02:12:18.085
!MESSAGE Widget disposed too early!
!STACK 0
java.lang.RuntimeException: Widget disposed too early!
at org.eclipse.ui.internal.WorkbenchPartReference$1.widgetDisposed(WorkbenchPartReference.java:171)
在网上搜索得知:
eclipse.ini文件加个参数
-vmargs
-Dorg.eclipse.swt.browser.XULRunnerPath=
在Fedora9中安装拼音输入法
保证Fedora 9联网的状态下
在application->system tools->terminal 应用程序->系统工具->终端
输入
su 回车
提示输入root密码
yum install scim 回车
系统会自动从一个镜uy像站点检索scim,并询问是否下载,选择y
下载完成后输入
yum install scim-pinyin 回车
提示和操作如上
然后输入
scim 回车
(笔者的电脑运行到starting SCIM后就没有反应了,不过没关系这时候可以按ctrl+c中断)
选择Fedora 9
System->Preference->Personal->Input Method
系统->首选项->个人->输入法
选择启用新特性,然后选择里面的SCIM,然后选择配置SCIM,
在进入后的界面中选择Global Set 全局设置,在这里设置激活热键即可,然后重新启动电脑,就可以在Fedora 9下面使用中文输入
法了 虽然有点麻烦 但毕竟fedora等众多linux桌面系统还很年轻,有很多不足之处。
参考资料:
http://www.5dlinux.com/article/6/2007/linux_9042.html
http://zhidao.baidu.com/question/62290384.html
http://www.linuxidc.com/Linux/2008-09/16011.htm
好久没写了,过了个年,过了七天猪的日子,吃了睡睡了吃中间偶尔看看电视,为假期准备了几个电影都没看,唉:-(忙,上了几天班了,怎么感觉这周过的这么慢呢,刚刚刚周四
昨儿看了一集struts2
总结几点
1、struts.xml中的package标签有个abstract="true"属性,如果为true,则这个package中不能有<action>标签,为true表示这个package为一个抽象package,就像java中的接口中不能有方法实现似的。
2、package标签还有个namespace属性,它关系到这个package中的action访问路径,默认是"",比如
<package name= "capinfo" extends= "struts-default" namespace="/hello">
<action name= "HelloWorld"
class= "com.capinfo.struts2.action.HelloWordAction" >
<result>/HelloWorld.jsp</result>
</action>
</package>
则jsp中则应为<form action="/hello/HelloWorld.action" method="post">,如果没有找到hello/HelloWorld.action则会寻找namespace为""的,也就是HelloWorld.action,如果再没有,就会抛出异常。
3、在struts1中可以有多个struts-config.xml的文件,只要在web.xml配置org.apache.struts.action.ActionServlet时加到config参数中,以逗号分隔,在struts2中也可以有多个struts.xml形式的文件,这次不需要修改web.xml了,在struts.xml中添加诸如
<include file=""/>就Ok了
4、关于struts各种参数的配置信息位于struts2-core.jar/org.apache.struts2/default.properties中,如果要修改里面的配置,有两种方式,一是在struts.xml中配置,例如<constant name="struts.devMode" value="true" />,二是在classess中建一个struts.properties,在里面配置比如struts.i18n.encoding=GBK,在struts2-core.jar/org.apache.struts2/default.properties中有一下这句注释,说明了struts.properties将覆盖default.properties中的配置
### Struts default properties
###(can be overridden by a struts.properties file in the root of the classpath)
###
就总结这么些先。
前两天实践了关于拦截器的具体实现,说实话关于底层实现还没有看明白,看jdk的源码中的
public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)
方法,好长啊
迂回一下,今儿看struts2的具体拦截器Interceptor怎么配置
配置可比自己写实现拦截器容易多了
1、首先写一个拦截器类,拦截器类有两只写法(目前俺知道的)
一种是显示com.opensymphony.xwork2.interceptor.Interceptor接口,com.opensymphony.xwork2.interceptor.Interceptor接口有三个方法destroy()、init()和String intercept(ActionInvocation actionInvocation),跟过滤器差不多
这里指出的是init初始化方法将在容器启动是调用这个方法。
package com.test.interceptor;
/**
* Created by IntelliJ IDEA.
* User: Administrator
* Date: 2009-1-15
* Time: 16:34:17
* To change this template use File | Settings | File Templates.
*/
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.ActionInvocation;
public class MyInterceptor implements Interceptor{
public void destroy() {
}
public void init() {
}
public String intercept(ActionInvocation actionInvocation) throws Exception {
System.out.println("test intercept begin");
String result = actionInvocation.invoke();
System.out.println("test intercept finish");
return result;
}
}
另一种就是继承com.opensymphony.xwork2.interceptor.AbstractInterceptor,这是个抽象类,并实现了com.opensymphony.xwork2.interceptor.Interceptor接口,分别实现了init和destroy方法,但什么都没做,继承AbstractInterceptor后,实现intercept方法就行了,
这里指出的是在intercept方法中执行actionInvocation.invoke();执行所拦截的action中的方法;
2、拦截器写完了剩下就是配置了,这里要用到struts.xml的组织结构<struts>中有<package>包的的概念,包与包之间可以继承extends,就像子类继承父类一样,子类将拥有父类的属性和配置,我们一般都继承extends="struts-default",而struts-default定义在struts2-core.jar 中的struts-default.xml中,struts-default包中定义了很多struts2提供的拦截器和拦截器栈(拦截器栈可以包含多个拦截器或拦截器栈),struts2的好多功能都是实现在这些拦截器中,其中有个<default-interceptor-ref name="defaultStack"/>标签定义了默认的拦截器,如果<action>配置中没有拦截器配置,那就调用默认拦截器,如果有拦截器配置,要么同时加上默认拦截器,要么在自己的package中加入设置默认拦截器的标签。
<package name="capinfo" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor" class="com.test.interceptor.MyInterceptor">
</interceptor>
</interceptors>
<action name="HelloWorld"
class="com.capinfo.struts2.action.HelloWordAction">
<result>/HelloWorld.jsp</result>
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<!-- Add your actions here -->
</package>
struts2局部类型转换
需求为:在页面的文本框输入一个x、y坐标,之间用","隔开,Action中有一个Point类型的属性,Point类里面有两个字段,分别是x,y,int型,要求当页面提交时将文本框中的字符串转换成Point对象,当Action返回到页面时将Point转换成字符串显示
1、首先做一个jsp用于输入和提交:point.jsp
<s:form action="Converter">
<s:textfield name="point" label="Point"></s:textfield>
<s:textfield name="point.x" label="Point.X"></s:textfield>
<s:textfield name="point.y" label="Point.Y"></s:textfield>
<s:submit label="submit"></s:submit>
</s:form>
2、再建一个用于显示的jsp-converter.jsp
<body>
<s:property value="point"/><br>
<s:property value="point.x"/><br>
<s:property value="point.y"/><br>
</body>
3、Action类 ConverterAction
public class ConverterAction extends ActionSupport{
private Point point;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public String execute()throws Exception {
return "success";
}
}
4、struts.xml
<action name="Converter"
class="com.test.struts2.action.ConverterAction">
<result name="success">/converter.jsp</result>
<result name="input">/point.jsp</result>
</action>
5、转换类 ConverterPoint
public class ConverterPoint extends DefaultTypeConverter {
@Override
public Object convertValue(Map context, Object value, Class toType) {
if(Point.class == toType){
String[] params = (String[])value;
params = params[0].split(",");
Point point = new Point();
point.setX(Integer.parseInt(params[0]));
point.setY(Integer.parseInt(params[1]));
return point;
}else if(String.class == toType){
Point point = (Point)value;
return "x=" + point.getX() + ",y=" + point.getY();
}
return super.convertValue(context, value, toType);
}
}
6、配置转换
在ConverterAction 类的同一目录下定义属性文件ConverterAction-conversion.properties,注意文件名,-conversion.properties为固定不变,ConverterAction为Action的名字,文件内容:
point=com.test.struts2.action.ConverterPoint
Ok了,这样就完工了