etmvc框架介绍教学内容.doc
Good is good, but better carries it.精益求精,善益求善。etmvc框架介绍-etmvc框架介绍如今的JavaWeb开发对于需求来说已经变得过于复杂。当今众多Java领域的Web开发框架不仅使用复杂,而且并没有很好的遵循DontRepeatYourself(DRY)原则。一、什么是etmvc?etmvc是一套轻量级简易高效的WEB开发框架,严格遵循MVC的思想。et一词源于1982年斯皮尔伯格执导的一部温馨科幻片E.T.(外星人),意思就是来自外星人的,不受束缚的MVC,开发者可以快乐地做WEB开发,而不受传统的烦杂折磨。etmvc是基于Java技术,为WEB开发提供的一套简易MVC框架。简易但不简单,其设计和实现借鉴业界众多的优秀框架,如struts,springmvc,ror,grails等,力图为Java开发人员提供一套高效的开发框架。· 基于java技术开发,继承其强大、稳定、安全、高效、跨平台等多方面的优点· 约定优于配置,免除开发过程中的配置之苦· 具有良好的自我扩展能力· 易于同spring等IOC框架进行集成· 从实用的角度出发,精益求精,从实际开发经验中提取有用的模型· 设计专门同EXTJS等框架进行整合的机制二、etmvc框架定位我们给这个框架的定位如下:· 简易:代码要简单,开发要容易。约定优于配置,再也没有XML的配置之苦。· 性能:在满足功能的前提下尽量地提高性能。· 实用:没有太多花哨的东西,一切从实用的角度考虑。三、授权协议etmvc框架采用LGPL授权。四、etmvc框架的组成etmvc框架包括mvc和一个可选的orm实现,可选的orm实现是一个ActiveRecord框架,独立于mvc,可以在非WEB的应用程序中使用。五、etmvc框架的安装1. 获取最新的框架:从本站获取最新的etmvc框架。2. 建立WEB项目,将下载的压缩文件解压至项目的/WEB-INF/lib目录中。3. 配置数据库,在/WEB-INF/classes目录中建立数据库连接配置文件activerecord.properties,配置示例:domain_base_class=com.et.ar.ActiveRecordBase com.et.ar.ActiveRecordBase.driver_class=com.mysql.jdbc.Driver com.et.ar.ActiveRecordBase.url=jdbc:mysql:/localhost/mydb com.et.ar.ActiveRecordBase.username=root com.et.ar.ActiveRecordBase.password=soft123456 com.et.ar.ActiveRecordBase.pool_size=24. 配置/WEB-INF/web.xml,添加一个过滤器,配置示例: <filter> <filter-name>etmvc</filter-name> <filter-class>com.et.mvc.DispatcherFilter</filter-class> <init-param> <param-name>controllerBasePackage</param-name> <param-value>controllers</param-value> </init-param> <init-param> <param-name>viewBasePath</param-name> <param-value>/views</param-value> </init-param> </filter> <filter-mapping> <filter-name>etmvc</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>5. 建立保存视图模板的目录/views。六、etmvc框架的基本概念1. controller:控制器是属于请求范围的,用于处理请求,创建或者准备响应。每次请求都会创建一个控制器实例,控制器的类名必须以Controller结尾,一般整个应用程序会创建一个控制器的基类2. ApplicationController,然后具体的其它控制器再继承之。3. action:每个URL操作将映射到一个action上,一个action是一个控制器的方法,一个控制器可以管理彼此相关的多个action。一个控制器中标准的action命名参考:o index:默认的动作o show:显示动作o create:新建动作o save:保存动作o edit:修改动作o update:更新动作o destroy:删除动作4. model:模型,是一个数据实体,将对应到具体的数据表中,这种映射关系是通过ActiveRecord实现的。所以数据表中的字段名就是模型对象中的属性名,不再需要用XML配置描述了。view:视图,etmvc支持多种视图,甚至一个action多视图,最常用的视图是JspView,在AJAX应用中是JsonView,下载处理二进制数据时是BinaryView,等等。关于etmvc的配置etmvc遵循“约定优于配置”的原则,通过文件的命名及存放位置来代替显式的配置,避免编写烦杂的XML配置文件。etmvc的配置只有一处,即在web.xml中配置一个filter,如下所示:<filter><filter-name>etmvc</filter-name><filter-class>com.et.mvc.DispatcherFilter</filter-class><init-param><param-name>controllerBasePackage</param-name><param-value>controllers</param-value></init-param><init-param><param-name>viewBasePath</param-name><param-value>/views</param-value></init-param><init-param><param-name>plugin</param-name><param-value>plugin.OcrServer</param-value></init-param></filter><filter-mapping><filter-name>etmvc</filter-name><url-pattern>/*</url-pattern></filter-mapping>其中,filter的初始参数有三个:controllerBasePackage,viewBasePath,plugin,说明如下:1controllerBasePackage是控制器的基包名称,如controllers,所有的控制器类必须在controllers包中,或者在controllers的子包中。控制器类必须以Controller结尾,必须继承Controller,比如有如下的控制器类:packagecontrollers;publicclassArticleControllerextendsApplicationControllerpublicViewshowImage(intid)throwsException/.publicViewdownload(intid)throwsException/.publicvoidcreate()控制器包名是controllers,控制器类名是ArticleController,有showImage等Action方法。2viewBasePath是存放视图模板的位置,如下所示:视图模板的目录结构有一定的规则,在viewBasePath目录下是控制器名称(小写),再往下是对应每个Action方法的视图文件。如ArticleController控制器中的方法create对应到/article/create.jsp视图文件,即执行控制器的create方法后,etmvc根据执行的结果找到对应的视图进行渲染。3plugin是插件的配置,一般情况下无须用到,所以不用配置该项,关于插件的使用留到后面的章节再作介绍。Hello,World经典示例我们利用etmvc来建立一个Hello,World的WEB应用程序。一、首先,建立新的WEB项目,引入et-mvc.jar和paranamer-1.3.jar,配置web.xml,加入一个过滤器,如下所示:<filter><filter-name>etmvc</filter-name><filter-class>com.et.mvc.DispatcherFilter</filter-class><init-param><param-name>controllerBasePackage</param-name><param-value>controllers</param-value></init-param><init-param><param-name>viewBasePath</param-name><param-value>/views</param-value></init-param></filter><filter-mapping><filter-name>etmvc</filter-name><url-pattern>/*</url-pattern></filter-mapping>我们看到,过滤器com.et.mvc.DispatcherFilter目前只有二个参数,controllerBasePackage指的是控制器的包名,viewBasePath指的是视图模板的存放目录。二、接下来,我们开始编写控制器HelloController,一般我们会编写控制器基类ApplicationController,我们的HelloController会继承它。注意到,控制器的包名是controllers,这就是前面配置中的controllerBasePackage配置值。packagecontrollers;importcom.et.mvc.Controller;publicclassApplicationControllerextendsControllerpackagecontrollers;importcom.et.mvc.TextView;publicclassHelloControllerextendsApplicationControllerpublicTextViewsay()returnnewTextView("hello,world");三、至些,我们的Hello,World程序编写完毕,部署后在浏览器地址栏输入http:/localhost:8080/helloworld/hello/say,将会输出hello,world字。controller 理解并使用控制器Updated Dec13,2009 by stwor.我们举个简单的例子说明一下从浏览器发送请求到服务器处理完请求返回信息给浏览器的过程。1、浏览器发出http:/localhost:8084/myweb/user/list这个请求,服务器将从这个URL分析出如下信息:myweb:上下文路径信息User:控制器信息list:动作信息2、服务器根据这个信息查找控制器UserController中的list方法,并执行之。3、服务器将查找名称是list.jsp的视图并将处理结果传递到视图,完成渲染过程。整个处理过程简单来说就是这样。每个请求都会创建新的控制器实例,控制器的类名必须以Controller结尾,必须继承Controller类,比如ApplicationController,HelloController等,控制器的Action方法允许继承,我们一般都会创建一个根控制器,然后让其他控制器统一继承这个根控制器。每个控制器允许有多个Action操作,这些操作将映射到相应的URL上。比如有如下的控制器:publicclassUserControllerextendsApplicationController publicvoidcreate() publicViewsave(Useruser)throwsException publicvoidlogin(Stringname,Stringpassword)throwsException publicvoidlogout()throwsException 将相应的URL映射到控制器的Action方法上:URLAction方法/user/createcreate/user/savesave/user/loginlogin/user/logoutlogout至此,我们看到编写控制器处理WEB请求就是这样简单。控制器的Action方法接受不同的参数,这些参数将自动绑定到Request的参数,方法可以返回不同的类型,比如void,String,JsonView,BinaryView等,etmvc将据此确定处理后以何种视图返回。下面我们以一个用户登录的例子来说明控制器的一般用法:1、建立控制器,如下所示:packagecontrollers;publicclassUserControllerextendsApplicationController publicvoidlogin() publicStringhandleLogin(Stringusername,Stringpassword)throwsException return"你输入的用户:"+username+"密码:"+password; 我们定义了二个Action方法,一个是login,该方法返回值是void,系统默认将寻找/views/user/login.jsp的视图进行显示,另一个是handleLogin,该方法将简单地将用户登录信息显示出来。2、我们来建立login.jsp视图: <formaction="<c:urlvalue="/user/handleLogin"/>"method="POST"> <p>用户名:<inputtype="text"name="username"></p> <p>密码:<inputtype="password"name="password"></p> <p><inputtype="submit"value="提交"></p> </form>我们看到FORM中的action的URL指向,这个URL将映射到我们控制器中的handleLogin方法,而该方法将返回String类型,etmvc将其解释了文本视图,所以将会在浏览器上显示登录的信息。action Action方法和控制器环境Updated Dec13,2009 by stwor.当请求到达时,etmvc将创建控制器对象,控制器对象会查找与“被请求的action”同名的public实例方法。如此看来,控制器的Action方法是允许被继承的。如果你希望某些方法不被作为action调用,可以将其声明为protected或者private。比如有如下的控制器:publicclassBlogControllerextendsApplicationController publicStringshow() return"showmethod" protectedStringcreate() return"createmethod" 当访问/blog/show时将输入框“showmethod”,而访问/blog/create时将有“Therequestedresource(/test1/blog/create)isnotavailable”的信息。Action方法允许使用控制器环境提供的一些对象:· request· response· session· servletContext· controllerPath· controllerName· actionPath· flash· exception他们的作用应该不言自明,其中flash对象的使用方法我们将分出一个主题专门作介绍。view 关于etmvc的视图Updated Dec13,2009 by stwor.我们来探讨etmvc如何使用视图,前面关于“Action方法”的介绍中我们提到,每个请求将会映射到一个Action方法。etmvc将根据Action方法的返回类型来决定使用何种视图,大体有以下三种:1. 返回void时将使用JSP视图。2. 返回String时将字符串直接输出至浏览器。3. 返回View或其子类时将使用对应的视图。下面我们来分别说明,如有如下的action方法:publicclassUserControllerextendsApplicationController publicvoidtest1() request.setAttribute("hello","hello,test1"); action方法“test1”的返回类型是void,这时etmvc将其解释为JSP视图,将会查找/views/user/test1.jsp的文件,文件内容: <body> <h1>HelloWorld!</h1> <p>$hello</p> </body>我们来编写返回类型是String的action方法:publicclassUserControllerextendsApplicationController publicStringtest2() return"hello,test2" 这时会将返回字符串“hello,test2”直接输出至浏览器。如果返回类型是View或其子类型,则etmvc会使用其定义的视图,如下所示:publicclassUserControllerextendsApplicationController publicJspViewtest3() JspViewview=newJspView(); view.setAttribute("hello","hello,test3"); returnview; publicJspViewtest4() JspViewview=newJspView("/common/other.jsp"); view.setAttribute("hello","hello,test4"); returnview; 上面例子中test3使用默认的JSP视图位置和目录/user/test3.jsp,而test4使用指定的视图位置和目录/common/other.jsp。我们现来看个JsonView的例子,JsonView能够处理多种数据结构,能够将其正确地转换成客户端需要的JSON串,这在AJAX的开发中非常有用,同EXTJS整合时也会很容易,如下所示:publicclassUserControllerextendsApplicationController publicJsonViewtest5() Map<String,Object>result=newHashMap<String,Object>(); result.put("success",true); result.put("msg","hello,test5"); JsonViewview=newJsonView(result); view.setContentType("text/html;charset=utf-8");/允许指定ContentType returnview; 上面例子运行结果将向浏览器输出"msg":"hello,test5","success":true。我们来总结一下,etmvc目前支持的视图包括:· JspView· TextView· FreeMarkerView· BinaryView· JsonViewextendview 扩展etmvc的视图Updated Dec13,2009 by stwor.etmvc内置了多种常用的视图,每种视图都有对应的renderer对象,视图对象中通过加上ViewRendererClass注解将renderer对象关联起来。比如JspView有相应的JspViewRenderer,JsonView有对应的JsonViewRenderer。如果要使用自定义视图,则可以扩展视图,扩展视图是很简单的事情,我们需要做二件事情:一是定义视图对象,二是定义renderer对象。假如我们要来定义一个JavaScriptView视图,用于向页面输出并执行一段JavaScript代码。首先定义视图对象,视图对象建议继承View对象:ViewRendererClass(JavaScriptViewRenderer.class)publicclassJavaScriptViewextendsView privateStringjs; publicJavaScriptView(Stringjs) this.js=js; publicStringgetJs() returnjs; publicvoidsetJs(Stringjs) this.js=js; 我们看到,视图对象仅是一个定义了需要的数据载体,其渲染输出是通过renderer对象完成的。下面看来一下renderer对象的定义:publicclassJavaScriptViewRendererextendsAbstractViewRenderer<JavaScriptView> publicvoidrenderView(JavaScriptViewview,ViewContextcontext)throwsException PrintWriterout=context.getResponse().getWriter(); out.print("<script>"+view.getJs()+"</script>"); out.close(); renderer对象扩展了AbstractViewRenderer,视图的渲染就是通过renderView方法实现的。好了,自定义的JavaScriptView扩展完成了,我们来看看怎样使用:publicclassTestControllerextendsApplicationController publicViewjstest() JavaScriptViewview=newJavaScriptView("alert(abc);"); returnview; 我们在控制器中定义一个Action方法,只要将该方法的返回类型设为JavaScriptView就行了。binders 利用etmvc中的模型绑定简化Action方法的编写Updated Dec13,2009 by stwor.我们以一个用户注册的例子来说明模型绑定问题。首先,建立一个用户注册表单: <h1>用户注册</h1> <formaction="<c:urlvalue="/user/save"/>"method="POST"> <p>名称:<inputtype="text"name="name"></p> <p>密码:<inputtype="password"name="password"></p> <p>确认密码:<inputtype="password"name="confirmPassword"></p> <p>邮箱:<inputtype="text"name="email"></p> <p>电话:<inputtype="text"name="phone"></p> <p><inputtype="submit"value="提交"><inputtype="reset"value="重置"></p> </form>现在编写控制器用以处理表单:publicclassUserControllerextendsApplicationController /* *用户注册页面 */ publicvoidregister() publicStringsave() Stringname=request.getParameter("name"); Stringpassword=request.getParameter("password"); StringconfirmPassword=request.getParameter("confirmPassword"); Stringemail=request.getParameter("email"); Stringphone=request.getParameter("phone"); if(!password.equals(confirmPassword) return"确认密码不对。" Stringinfo="name:"+name+"<br/>" +"password:"+password+"<br/>" +"email:"+email+"<br/>" +"phone:"+phone; returninfo; · 我们可以通过控制器环境提供的request对象获取表单数据,进而进行处理。· 但我们有更好的处理方法,我们建立一个User对象来描述表单,这个相当于struts中的ActionForm,· publicclassUser privateStringname; privateStringpassword; privateStringemail; privateStringphone; privateStringconfirmPassword; /getset.· 现在,我们改写控制器中的save方法:· publicclassUserControllerextendsApplicationController /* *用户注册页面 */ publicvoidregister() publicStringsave(Useruser) if(!user.getPassword().equals(user.getConfirmPassword() Stringinfo="name:"+user.getName()+"<br/>" +"password:"+user.getPassword()+"<br/>" +"email:"+user.getEmail()+"<br/>" +"phone:"+user.getPhone(); returninfo; · 我们看到etmvc自动将表单数据绑定到Action方法的参数中。我们把定义的User称作模型,etmvc会根据Action方法的参数自动将请求参数绑定进来,Action方法的参数类型和顺序可以是任意的,对于复杂的对象类型,可以用Bind注解说明绑定的前缀,如Bind(prefix="user")Useruser,这时页面表单项的名称就不能是name,password,而应是user.name,user.password。· etmvc处理大部分常用的数据类型绑定,如果想自已处理数据转换绑定,可以实现DataBinder接口,如:· publicclassDateBinderimplementsDataBinder publicObjectbind(BindingContextctx)throwsException /. returnnull; · 然后进行注册:· DataBinders.register(java.util.Date.class,newDateBinder();· 这时候就可以在Action方法中使用java.util.Date参数类型了。ormbase ORM-ActiveRecord基础· Updated Dec13,2009 by stwor.etmvc中访问数据可以使用JDBC,HIBERNATE等,鉴于JDBC的烦琐和HIBERNATE的复杂,我们同时提供了一个ORM的简易实现版本ActiveRecord。在大多数中小型WEB系统中,使用ActiveRecord就足够了。1、使用前须将et-ar.jar,asm.jar,cglib.jar等包引入项目,然后进行配置activerecord.properties:domain_base_class=com.et.ar.ActiveRecordBasecom.et.ar.ActiveRecordBase.driver_class=com.mysql.jdbc.Drivercom.et.ar.ActiveRecordBase.url=jdbc:mysql:/localhost/mydbcom.et.ar.ActiveRecordBase.username=rootcom.et.ar.ActiveRecordBase.password=soft123456com.et.ar.ActiveRecordBase.pool_size=2在上面配置中我们配置了MYSQL数据库连接,配置文件activerecord.properties放在CLASSPATH能找到的地方就好。2、我们来建立一张数据表:createtableusers(idintprimarykeyauto_increment,namevarchar(10)defaultnull,addrvarchar(50)defaultnull,emailvarchar(50)defaultnull,remarkvarchar(50)defaultnull)然后建立对应的域对象:Table(name="users")publicclassUserextendsActiveRecordBase IdprivateIntegerid; ColumnprivateStringname; ColumnprivateStringaddr; ColumnprivateStringemail; ColumnprivateStringremark; /get,set.我们的域模型对象继承自ActiveRecordBase,到些,ORM就建立完成了,我们看到,不需要复杂的配置文件,仅用几个简单的注解就完成了。3、基本的CRUD操作增加记录: Useruser=newUser(); user.setName("name1"); user.setAddr("addr1"); user.setEmail("name1"); user.save();修改记录: Useruser=User.find(User.class,3); user.setRemark("userremark"); user.save();删除记录: Useruser=User.find(User.class,3); user.destroy();查询记录: List<User>users=User.findAll(User.class); for(Useruser:users) System.out.println(user.getName(); 条件查询: List<User>users=User.findAll(User.class,"addrlike?",newObject"%百花路%"); for(Useruser:users) System.out.println(user.getName(); 我们看到,借助ActiveRecord,操作数据是如此容易。user_admin_example 利用etmvc编写用户管理小例子Updated Dec13,2009 by stwor.我们来编写一个用户资料管理的小程序,旨在说明etmvc的基本用法。需具备的基础:· 理解基本控制器· ActiveRecord操作基础现在建立一个测试用的表结构:createtableusers(idintprimarykeyauto_increment,namevarchar(10)defaultnull,addrvarchar(50)defaultnull,emailvarchar(50)defaultnull,remarkvarchar(50)defaultnull)接下来建立对应的模型对象:Table(name="users")publicclassUserextendsActiveRecordBase IdprivateIntegerid; Column NotEmpty(message="用户名称必须填写") privateStringname;