#
java在桌面软件的失利,很大程度上取决与她运行环境的陪着复杂度,还有随时带的一个庞大的jre环境。有时候我们并不需要jre中全部的类库支持,我们只需要一些对我们项目有用的类库,能否有一种通用的方法来抽取jre中的这些对我们有用的部分呢?google了下找到了几篇文章介绍这个的。主要就是用verbose参数运行jar,然后观察java载入了多少java类,然后手动或者写个程序自动的吧这些类打包和jvm打包为一个全新的jre环境。这种方法是可行的,但是却是不通用,而且这种方法还有一个很大的弊端,当有些类导入到我们项目中,但是在verbose的时候没有用到(比如一些异常类),我们就不会导入,最终可能在发布运行的时候就用到了,这样可不妙。那么是否还有其他方法来瘦身jre环境呢,然后通过随身附带jre发布java程序?答案一定是有的,我已经着手在开发这个应用,我把她起名为BuildJre。
一,可行性分析(我们加上在win系统下):
java.exe是java运行的一个入口程序,当我们键入明了 java className的时候,首先启动都是这个程序,然后这个程序回去查找可用的jre库,一般是先搜索本目录和父亲目录,如果接着搜索环境变量,判断是否为jre的依据是,首先java.exe查找怀疑目录(比如父目录)的bin下有没有java.dll,如果找到,那么他就判定这个是jre目录然后查找lib\i386下的jvm.cfg,最后更具这里面的参数去启动bin\client或者bin\server下的jvm.dll,这个才是真正的java虚拟机,到这里,java.exe把控制权全部交给jvm,然后jvm就初始化,分配内存等,运行程序了,运行程序期间导入的jdk包,都在jre目录下的lib\rt.jar下。
说道这里,我们发现,其实不用环境变量,只要有jre环境就能运行java程序,这使得我们更加坚定java程序也可以桌面化,因为他也是可以不用配置那么麻烦的环境变量直接运行的。再回到瘦身来,刚才说了,jdk中所有的以来包全部位于jre\lib\rt.jar下,我们要廋的就是这个,40多M的rt,我们通过类依赖抽取,对于一个普通的java程序,预计可以廋到小于10M,然后配合java.exe,java.dll,等几个小的程序,预计目标是平均廋身到15M以内。
二,实施思路,用verbose方法不通用,不能在程序内部抽取jre,而且还有可能遗漏依赖项,不足提倡。我们架设有一个标志的依赖说明库,比如ArrayList这个类依赖的所有包都一一对应,那么我们如果在程序里import ArrayList的话,那么我们可以迅速抽取相关的依赖包,然后在整个项目的所有import中去重复,不就ok了?现在的问题在于:
1,不是所有的jdk包都需要import的,比如java.lang下就不用import
2,有些jdk内部类在同一个包下不用写import也一样依赖。
3,计算jdk内部依赖估计要很长实践,因为文件很多,依赖很复杂。
这些问题基本上都有解决方法,我已经开始着手解决。
希望有一天,我们的java项目发布,只要带上10M的小型环境,也不用配置环境变量,双击,ok。。哈哈
这年头,webgame一个一个的冒出来,令我们应接不暇,有人说webgame是一场新的泡沫,也有人说是互联网新的机会,有人说webgame是小公司叫板游戏行业的机会,也有资深游戏人士说小公司做webgmae没戏(盛大高管说,因为没有品牌和玩家资源)。不管怎么样,webgame的兴起已经无法阻挡,包括我们公司,也是众进军者中的一个。
webgame游戏商进军的主要两个领域是 策略类游戏(往往以js,ajax技术和纯通的web技术为基础),和flash休闲社区游戏(以flash as3等技术为基础)。策略类游戏很早就有了,甚至比现在的门户网站还早,只是那个时候没有现在这么兴起,时下具有代表性的主要是一些三国,战争类游戏,像盛大这种大游戏公司也介入不少,连baidu这种重来不碰游戏的公司都开始进入了。而flash游戏相对来说比较少,比如梦境家园(纯休闲娱乐,可以k歌),比如热舞街(劲舞团的web版),天空左岸 和 富豪街 等都不错。还有两个我本人比较期待的还没有公测的flash网游,一个是昆仑online,一个是和热舞街,富豪街同一个公司的 口袋宠物。看他们的游戏截图已经非常类似传统的大型游戏了。当然,更期待的是我们在开发的flash网游,哈,内容和名字现在还不能透露(小小透露下,我们的网游pk模式和现在任何一种网游的pk模式都不同,挺好玩的哦)。
。。。。不想说了。。想起来一本书上的一句话“真正有想法的人,已经埋头在实现自己的想法了,不会把自己的想法写出来,在网上瞎扯淡的,都是没事干的。”
游戏前台主要以flash as3 为主,后台用java,目前已经初步做出一个原型,包括用户行走,多用户移动同步,地图场景与主程序分离,场景加载等等功能,地图编辑器也已经做的差不多了,计划今天能完成,如果完成的话,就可以直接拿给美工去做地图场景了,最终导出一个xml文件和相关的资源(图片等),主程序通过这个xml文件加载场景。
这几天主要的任务包括 客户端UI统一界面设计,需要做到高耦合,让ui界面通过xml文件配置,服务器端数据库的设计,主程序调用外部swf模块的企业级设计,游戏任务脚本语言的初步设计,等等。
以后开始正式要做网络游戏啦,flash前台,java后台。嘿嘿
还没有整理出完整的api,里面有一个简单的例子。
下载
IMVC对ajax有了很好的支持。主要体现在两方面。
一 ajax View类型支持。Imvc的视同是通过一个View类来返回的,在action中通过return new View("/xxx.html")返回一个视图,然后IMVC会通过Value中的数据渲染这个视图。这是一般的流程,有些特殊的流程可以返回其他类型的View,我们先来看看View类的代码:
public final class View implements Cloneable{
/**
* 属性介绍:普通的view,通过模板转换
*/
public static final int TYPE_VIEW=1;
/**
* 属性介绍:转向,不改变url
*/
public static final int TYPE_REDIRECT=2;
/**
* 属性介绍:专心 ,改变url
*/
public static final int TYPE_REDIRECT2=3;
/**
* 属性介绍:直接返回string,path的值
*/
public static final int TYPE_AJAX=4;
public static final int TYPE_EXCEPTION=5;
private String path;
private int type=1;
public View(String path){
this.path=path;
}
public View(String path,int type){
this.path=path;
this.type=type;
}
public View(Map map){
JSONObject jsono=JSONObject.fromObject(map);
path=jsono.toString();
type=TYPE_AJAX;
}
public View(List array){
JSONArray jsona=JSONArray.fromObject(array);
path=jsona.toString();
type=TYPE_AJAX;
}
public View(Object bean){
JSONObject jsono=JSONObject.fromObject(bean);
path=jsono.toString();
type=TYPE_AJAX;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public View clone(String path){
View v=cloneBase();
v.path=path;
return v;
}
public View clone(String path,int type){
View v=cloneBase();
v.path=path;
v.type=type;
return v;
}
public View clone(Map map){
View v=cloneBase();
JSONObject jsono=JSONObject.fromObject(map);
v.path=jsono.toString();
v.type=TYPE_AJAX;
return v;
}
public View clone(List array){
View v=cloneBase();
JSONArray jsona=JSONArray.fromObject(array);
v.path=jsona.toString();
v.type=TYPE_AJAX;
return v;
}
public View clone(Object bean){
View v=cloneBase();
JSONObject jsono=JSONObject.fromObject(bean);
v.path=jsono.toString();
v.type=TYPE_AJAX;
return v;
}
private View cloneBase(){
View v=null;
try {
v = (View) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return v;
}
}
我们主要关注以下几个变量:
/**
* 属性介绍:普通的view,通过模板转换
*/
public static final int TYPE_VIEW=1;
/**
* 属性介绍:转向,不改变url
*/
public static final int TYPE_REDIRECT=2;
/**
* 属性介绍:专心 ,改变url
*/
public static final int TYPE_REDIRECT2=3;
/**
* 属性介绍:直接返回string,path的值
*/
public static final int TYPE_AJAX=4;
public static final int TYPE_EXCEPTION=5;
第一个是普通的View,通过ViewFactory.getView("/tt.html")这个方法返回的是普通的view,也就是可以通过IMVC渲染的视图,而TYPE_REDIRECT则是返回一个跳转view,可以跳转到下一个action,TYPE_REDIRECT2也是一个跳转view,不过是改变URL地址的view。TYPE_AJAX就是ajax试图了,也是今天要讲的主角了,至于最后一个TYPE_EXCEPTION,是把异常返回到客户端浏览器到view,这里暂时不考虑。我们可以通过这样一个构造函数创造出ajax试图,比如new View("这是ajax信息",View.TYPE_AJAX),或者通过ViewFactory.getView("这是ajax信息",View.TYPE_AJAX)也是一样,不过用factory创建的对象是通过对象的clone创建的,能节省一定的性能开销。当返回的是一个ajax View的时候,信息就会直接返回,而不是通过渲染试图,比如上面的就直接返回“这是ajax信息”给客户端,如果这个action是由客户端ajax请求的话,直接返回数据,是不是很方便呢?
接下来的ajx特性也许会让你觉得更方便,比如以下代码:
....action前面的内如.....
User u=new User();
u.setAge(1);
u.setName("汪汪汪");
return ViewFactory.getView(u);
这样的返回会直接在客户端打印出 {"age":1,"name":"汪汪汪"};也就是IMVC把对象映射成立JSON(一种js对象的String形式),这个返回数据在客户端直接可以调用,比如data.name就直接调用出“汪汪汪”,是不是很方便?而且IMVC还支持把List,数组,Map,还有对象相互无限级嵌套返回成JSON数据,这将大大增加AJAX开发的敏捷性和清晰性。
二 ajax Chain支持。我们假设有一个全部ajax的网页,里面有几个div中的数据都是通过ajax的方式向服务器请求的,那么每个div都会请求一次ajax action,这样就导致了请求次数频繁,资源的浪费,IMVC提供了一种ajaxChain的概念,可以通过一个url请求多个action,然后把数据自动合并,比如下面的url
http://xxx.com/ajaxChain.x?id=|one,two?id=1|
这个url请请求了两个action,然后把action数据合并,比如本来one.x返回的数据是{"name":"111"},而two返回的数据是 {"name":"2222"};则现在应该返回的是{"one":{"name":"111"},"two?id=1",{"name":"2222"}},这样,ajaxChain支持无数个action的连接。这样以后可以将多个ajax合并为一个ajax,节省服务器资源。
好了,IMVC的ajax支持就讲到这里。
这里所谓的非侵入性,是指一定程度上的耦合性,比如IMVC和待开发项目的耦合性,servlet容器和IMVC的耦合性,IMVC内部处理的耦合性等等。
1.action非继承。由于java语言不允许多重继承,如果action被框架所迫需要继承类的话,那么这个action的扩展性将受到一定的限制,比如struts的继承性就设计的比较失败。
2.formBean的无侵入,IMVC中的formBean不需要继承人和类,甚至不需要实现任何接口,完全的一个pojo实体就能胜任。
3.半servlet容器相关性,之所以说是半,因为IMVC的容器无关性是间于struts和webwork之间的,struts的action接受 httpServletRequest和HttpServletResponse类实例作为参数,另测试变得避免麻烦(虽然有工具可以辅助测试),这种 servlet完全相关性的设计,让action中获取servlet数据变得容易,但是却带来了测试痛苦的后果。而反过来,webwork的 action中不需要传入任何servlet相关部件,webwork通过一个转回去把servlet中的数据拷贝到一个容器无关类。非常有利于测试,但是对于在action中获取servlet数据变得不够直观(可以获取的),而且,每次请求都拷贝数据也有碍于性能的提升。IMVC的设计则介于两者之间。在IMVC的action中没有传入servlet任何部件,但是可以通过InstantContext获得request和response(注意不是获取request的数据,而是request,不用花费拷贝到性能)。但是,在拦截器设计中,传入的却是 servlet部件,因为拦截器一般不会用于action单元测试,而且如果你对上面的action半容器无关性对于单元测试和获取cookies的数据有疑惑,那么可以在拦截器中获取你想要的cookie,然后传入拦截器的另一个参数Value,action通过Value获取cookie,这样一来,明明半容器无关性的action测试,却可以通过拦截器来实现完全容器无关的action,这样一来,既满足性能需求,又满足测试需求。
4 拦截器的天下。和webwork一样,IMVC中的拦截器是相当重要的组成部分。可以配置全局拦截器,路径拦截器,ajax链(这个以后会详解)拦截器,有趣的是,我们还有一个文件上传拦截器,IMVC是集成文件上传到,可以通过在action几行代码实现一个文件上传,而一般我们要更具自己的特性来处理上传完后的文件或者自定义的取名字,在或者做自己的缩略图等等。IMVC设计了一个文件上传拦截器,可以通过实例一个拦截器来实现这些功能,非常方便。
IMVC(InstantMVC简称)有几个比较核心的接口,通过对这几个接口的了解,可以更深入的了解IMVC到核心机制。
1.IAction接口
action是整个MVC的核心,如果了解struts或者webwork等MVC框架的朋友应该
知道,action是一个用户处理模块,当MVC容器接受到一个请求的时候,他会通过一定的方法获得一个相应的action类,然后执行action类中
相应的方法,最后返回一个视图给客户端,这就是最普通的mvc框架的流程。和其他框架的action类似,IMVC的action接口也有一个核心方法,
如下
public interface IAction {
/**
* 属性介绍:验证器,放入Map value 的key
*/
public static final String MVC_STATIC_validation="__validation";
/**
* 属性介绍:文件上传 Map value中的key
*/
public static final String MVC_STATIC_createUpload="__createUpload";
/**
* 属性介绍:这是编辑器
*/
public static final String MVC_STATIC_editor="__editor";
/**
* 方法说明:action的核心方法
&
nbsp; * <
span style="color: #808080;">@param object 如果是post方法,object就
是该action对应的form,如果是get方法并且配置get方法没有form
* 那么这里就是null,如果配置get方法也是有form的,这里也是form
*
&
nbsp; * <
span style="color: #808080;">@param value 一个map,在
action中添加内容到view都往这里添加
* @return
* String
*/
public View execute(Object object,Value value);
}
前
面三个变量这里暂时不说,我们来关注最后一个方法,execute,任何action都需要实现这个接口,同时也就是说必须在action中有这个方法。
这个方法有两个传入变量Object和Value,第一个是想要的formBean,如果是get方法并且没有配置get方法设置form,那么这个时候
就是null,如果是非get方法,而且还传入了参数,那么IMVC会自动封装相应的form传入到这个。第二个Value参数,Value也是一个很核
心的接口。在IMVC中有ValueImpl类来实现。
Value 接口:
public interface Value {
public String getString(String key);
public String[] getArray(String key);
public void setObject(String key,Object value);
public Object getObject(String key);
}
ValueImpl 类:
public final class ValueImpl extends HashMap implements Map,Value,InstantValue{
//InstantValue
public void setArray(String key ,String[] arr){
super.put(key, arr);
}
//user Value
public String[] getArray(String key) {
return (String[])super.get(key);
}
public Object getObject(String key) {
return super.get(key);
}
public String getString(String key) {
Object o=super.get(key);
if(o==null){
return null;
}
if(o instanceof String[]){
return ((String[])o)[0];
}else{
return null;
}
}
public void setObject(String key, Object value) {
super.put(key, value);
}
//
以下实现clone。。提供性能
private ValueImpl cloneBase(){
ValueImpl vimpl=(ValueImpl) super.clone();
vimpl.clear();
return vimpl;
}
public static ValueImpl valueImpl=new ValueImpl();
public static ValueImpl cloneSelf(){
return valueImpl.cloneBase();
}
}
这个类也相当简单,我们看第一句:
public final class ValueImpl extends HashMap implements Map,Value,InstantValue
说
明这个类 继承了HashMap,实现了Map,Value,InstantValue 三个接口。这三个接口其实就是三个权限版本,比如Value是用
户操作权限,我们看到在action中传入的是Value,但是在IMVC内部操作的时候是把ValueImpl类转换为InstantValue借口的
InstantValue 接口:
public interface InstantValue {
public void setArray(String key,String[] value);
}
这个几口只有一个方法,这个方法是不会暴露给用户的,是提供IMVC内部设值用的。
下面还有一个拦截器接口
IInerceptor 拦截器接口:
public interface IInterceptor {
public void execute(HttpServletRequest request,HttpServletResponse response,Value value);
}
这个接口也相当简单,只有一个方法,传入request和response参数,同时还有一个Value参数,这个Value上面已经说过,是一个用户操作的数据接口。
整个IMVC流程图简单来说如下:
首先,请求来了后,IMVC会创建一个ValueImp转换为Value传给前拦截器(如果没有设
置就不用),拦截器操作完毕,在把这个ValueImp转换为InstantValue接口传给IMVC内部操作,操作完毕接着把它转化为Value接口
供用户Action操作,最后执行后拦截器,执行完毕转换为Map借口供模板引擎渲染试图。
一个ValueImp要转换为三种权限接口,所以他的实现就要implements 三个接口。
InstantMVC框架的基本功能基本上已经完成,框架的接口设计(抽象层)也已经完
工,以后修改大概不会有很大的接口变动,这里就贴出一个比较简单的hello world程序。
&
nbsp; 首先导入InstantMVC(一下简称IMVC)的包,和相应的依赖包(主要一些开源的包,比如
commons等)
然后再eclipse中新建一个web项目。。这个就不用说了吧。
然后在classPath下创建一个配置文件 mvcConfig.xml(名字任意起),内如大概如下:
<baseConfig
actionPackageBasePath="test.action"
formPackageBasePath="test.form"
templateBasePath="/template"
resourceBasePath="/re"
urlPostfix=".x"
webUrl="yao.com:8282"
/>
<optionalConfig
isOpenActionCache="false"
isOpenValidationCache="false"
isGetMethodHasForm="false"
isOpenAjaxIdentityValidate="false"
fileUploadBasePath="/upload"
fileUploadMax="1974592963"
fileUploadFormat="pdf,jpg,gif"
printOutCharacter="UTF-8"
templateCharacter="UTF-8"
uploadCharacter="UTF-8"
isOpenFreemarkerCache="false"
/>
前面那个 baseConfig是必须设置,后面optionalConfig是可选,可以不设置,IMVC有默认设置。具体的配置如下:
必填:
actionPackageBasePath :基础action包根目录
formPackageBasePath:基础form包根目录
templateBasePath:基础模板文件根目录
resourceBasePath:InstantMVC自带的资源文件目录
urlPostfix:action请求后缀
webUrl:网站域名,比如yao.com主要用于ajaxView的权限检测
可选:
isOpenActionCache="false" :是否开启action的缓存,也就是是否设置action为单例
isOpenValidationCache="false":是否开启检验框架的缓存
isGetMethodHasForm="false":是否为get方法也设置form填充
isOpenAjaxIdentityValidate="false":是否开启ajaxView的权限验证(不能跨域调用)
fileUploadBasePath="/upload":文件上传根目录,默认是/upload
fileUploadMax="1974592963":上传文件最大 ,可选,默认1048576=1024×1024 b
fileUploadFormat="pdf,jpg,gif":上传允许默认的格式,可选,默认为 pdf,jpg,gif,txt
printOutCharacter="UTF-8" : #可选,默认为UTF-8,表示通过action直接打印到客户端字符的编码,一般用到ajax发生
templateCharacter="UTF-8" :#可选,默认为UTF-8 ,表示通过模板方式显示到客户端的编码,一般用到直接的请求
isOpenFreemarkerCache="false":#是否开启freemarker模板缓存
最基础的配置就这些了,后面那个可选其实也可以去掉。
然后我们在项目中新建立一个包
test.action.test
然后在包下新旧一个java类:Hello:
public class Hello implements IAction{
public View execute(Object object, Value value) {
&
nbsp;
value.setObject("<
/span>hello",
"hello,欢迎来到
InstantMVC的世界。。。
");
return ViewFactory.getView("/test.html");
}
}
ok,然后我们在 web项目根目录下创建一个模板文件夹 template
在template下创建一个html文件 :test.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>test.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
${hello}<br />
</body>
</html>
很
简单的Html,里面只有一个地方需要主意的就是 ${hello}这个东西,还记得上面Hello.java中的
value.setObject("
hello"
, "hello,欢迎来到InstantMVC的世界。。。");
吗?其实这就是取出hello中的值。好一切配置都完成。额。好像还缺点什么,对,没有配置web.xml,下面是基本的 配置:<
br />
<servlet>
<servlet-name>instantMVCController</servlet-name>
<servlet-class>yao.instant.mvc.sevlet.InstantFrontController</servlet-class>
<init-param>
<param-name>mvc_config</param-name>
<param-value>/mvcConfig.xml</param-value>
</init-param>
<init-param>
<param-name>single_config</param-name>
<param-value>/instant.single</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>instantMVCController</servlet-name>
<url-pattern>*.x</url-pattern>
</servlet-mapping>
其
中
yao.instant.mvc.sevlet.InstantFrontController
是IMVC的前端拦截器,有两个参数,第一个是刚刚写的配置文件mvcConfig.xml相对于classPath的路径,第二个是IMVC内建的一个
对象管理容器的配置,这里可以先不写(或则在classPath下新建一个空的文件Instant.single,内容不用写)。下面那个是url映射,
把.x的后缀映射到IMVC框架。好了,一切的搞定,下面就运行
启动tomcat,在浏览器中输入http://localhost:8080/test/hello.x 就会看到一下结果:
看,一个简单的helloworld程序就完成了。下面我们回顾一下这个过程是怎么进行的。
首先,我们先回顾下我们的配置文件中有一个配置选项:
actionPackageBasePath="test.action"
这
个选项表示IMVC将会首先通过这个路径去寻找相应的匹配url的action,比如我们上面的url是:/test/hello.x 那么IMVC会首
先寻找 test.action.test包下的Hello类,如果没有存在,会报异常,如果存在,就执行Hello类的execute方法。在
execute方法最后返回了一个View,其中一个参数是模板位置,比如本例中是View("/test.html"),那么这个文件在哪呢?IMVC
又是怎么去寻找的呢,再回来看配置文件,其中的一个参数:
templateBasePath="/template"
这
个参数的意识就是吧web目录下的template作为主要的模板文件的根目录,此例中/test.html就是寻找的
/template/test.html文件,然后渲染模板,会把其中的${hello}参数渲染为 action中通过value这个对象设置的值,比
如本例中是:value.setObject("hello", "hello,欢迎来到InstantMVC的世界。。。");<
br />
至此,一个简单的get方法的IMVC流程结束。
这里其他的功能没有说道,比如View中有一种专门的返回ajax的View类型,比如还有拦截器,比如还有form填充和参数获取等都没说,下次再详细说明。
ps:InstantMVC目前还在内部修改完善,还不能提供版本下载。
InstantMVC是我最近开发的一个j2ee轻量级MVC框架,写这个框架前刚好做完一个webwork+spring+InstantORM的项
目,对于开发过程中的一些不舒服的地方,就像要改进着试试写一个框架,于是就开始写了,写这个框架的冲动主要有以下几点:
1.讨厌的action配置,无论是strtus还是webwork,都有一大堆的action配置文件,strtus加上bean就更多,如果
webwork配合spring,那么一个action就要配置一个spring Bean,一个webwork
action映射,随着项目的扩大,后来实在是让人有些受不了,再则,随着项目的扩大,action数目的增加,每次改动重新启动服务器的时间浪费就更
大,所以项目越来越大,感觉越来越痛苦,虽然配置型的action,对于项目的移植有一定的好处,但是一般的项目是很少回过头去修改action映射,就
算修改,在java文件中修改也是可以接受的。
2.关于验证,struts和webwork的验证都是基于xml配置的,就我个人而言,是比较讨厌xml配置这个东西的,所以我一直用不惯他们的验证框
架,而且一旦用到验证框架,必须用到UI组件,在webwork中用freemarker作为模板的时候,UI组件是比较费资源的(可能成为潜在的性能瓶
颈),如果有一个不用UI组件而且外面封装客户端和服务器端验证的MVC框架,我想会比较爽。
3.关于view,我比较喜欢springMVC中的那种直接在action中return的形式,webwork和struts的配置方式我也很不喜欢。
4.应该是性能考虑,webwork的action非单利可能导致性能问题(虽然没有被充分证明),struts2也走了这条路。
基于这些考虑,我打算开发自己的MVC框架,而且现在已经小有所成,基本功能已经完成,下面简单讲下InstantMVC框架的主要特征
1.零配置,零配置不是说没有配置,而是说不用配置action和result view,整个mvc框架只有一个整体的配置文件,所有映射关系都是通过默认规则来建立的。
2.类似action/form
形式,这里说是类似,因为InstantMVC可以配置让get方法是否支持form,也就是get方法可以不用form,直接通过一个Map获得请求参
数,也可以配置get填充form形式,InstantMVC的action可以配置为是单利或者非单利,不过一般在action中不推荐存放非线程安全
的变量,所以建议配置为单利。
3.action中两个参数一个是Form的Object,一个是Map,容易单元测试,不需要引入Servlet部件,但是对于一些session等操
作可以通过InstantContext获得HttpSerlvetrequest操作,可以说InstantMVC对于容器无关性是介于webwork
和struts之间的。
4.最简单的验证集成方式,所有验证代码写到action中,在view中不用配置UI组件,支持客户端和服务器端双重验证,可以单独开启一方关闭一方。
5.ajax
View的集成,这里的集成不像dwr那样完全集成,而是一种半集成方式,客户端用到ajax框架还是需要用户自己选择,这样提供了很大的灵活性。
InstantMVC的View有好几种形式,比如挑战到另一个action的view,直接返回的view,ajax的view等,
InstantMVC的ajax是和普通的action一样的,只不过返回一个ajax的View就成了ajax了。ajax的view可以返回任何对象
的json。在客户端很方便的获得,这一点有点像dwr的返回结果,不过dwr需要配置,InstantMVC不用。而且我们可以设置开启ajax的安全
验证,开启后将不允许其他域方法ajax的action。
6.支持AOP拦截器,模仿webwork那样,可以自定义拦截器。
7.集成了上传组件,和验证一样,可以在action中配置。
大概就是这些特性,这些特性都很让我着迷。现在这些特性基本上都能工作,不过稳定性兼容性方面还有待提升,同时还需要大量的性能方面考虑(虽然现在的性能比其他MVC只会高不会低)。今天刚把blog搬到这里来,以后这里会主要写关于我的框架的一些问题等。