《2022年Etmvc学习文档 .pdf》由会员分享,可在线阅读,更多相关《2022年Etmvc学习文档 .pdf(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Etmvc 学习文档etmvc 框架介绍如今的 Java Web开发对于需求来说已经变得过于复杂。当今众多Java领域的 Web 开发框架不仅使用复杂,而且并没有很好的遵循Don t Repeat Yourself (DRY )原则。之前看过struts, spring mvc, ror, grails 等框架,其中最欣赏ror 了, struts 的灵活性对于多数中小型项目而言显得对于多余。特别是在AJAX如此盛行的今天,现有的框架对AJAX的支持显得不足。于是,萌生了开发一套简易框架的念头,再后来就有了现在的etmvc。一、什么是etmvc?etmvc 是一套轻量级简易高效的WEB 开发框
2、架,严格遵循MVC 的思想。 et 一词源于 1982年斯皮尔伯格执导的一部温馨科幻片E.T.(外星人 ),意思就是来自外星人的,不受束缚的 MVC ,开发者可以快乐地做WEB 开发,而不受传统的烦杂折磨。二、 etmvc 框架定位我们给这个框架的定位如下:简易:代码要简单,开发要容易。约定优于配置,再也没有XML 的配置之苦。性能:在满足功能的前提下尽量地提高性能。实用:没有太多花哨的东西,一切从实用的角度考虑。三、授权协议etmvc 框架采用 LGPL 授权。四、 etmvc 框架的组成etmvc 框架包括mvc 和一个可选的orm 实现,可选的orm 实现是一个ActiveRecord
3、框架,独立于 mvc,可以在非WEB 的应用程序中使用。五、 etmvc 框架的安装获取最新的框架:从本站获取最新的etmvc 框架。建立 WEB 项目,将下载的压缩文件解压至项目的/WEB-INF/lib目录中。配 置 数 据 库 , 在 /WEB-INF/classes目 录 中 建 立 数 据 库 连 接 配 置 文 件activerecord.properties, 配置示例:源码复制打印domain_base_class=com.et.ar.ActiveRecordBase 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - -
4、- 名师精心整理 - - - - - - - 第 1 页,共 19 页 - - - - - - - - - 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=2
5、 配置 /WEB-INF/web.xml ,添加一个过滤器,配置示例:源码复制打印etmvc com.et.mvc.DispatcherFilter controllerBasePackagecontrollers viewBasePath/viewsetmvc /* 建立保存视图模板的目录/views。六、 etmvc 框架的基本概念controller :控制器是属于请求范围的,用于处理请求,创建或者准备响应。每次请求都会创建一个控制器实例,控制器的类名必须以Controller 结尾,一般整个应用程序会创建一个控制器的基类ApplicationController ,然后具体的其它控制器
6、再继承之。action:每个 URL 操作将映射到一个action 上,一个action 是一个控制器的方法,一个控制器可以管理彼此相关的多个action。一个控制器中标准的action 命名参考:oindex: 默认的动作oshow:显示动作ocreate:新建动作osave:保存动作oedit:修改动作oupdate:更新动作odestroy:删除动作model:模型,是一个数据实体,将对应到具体的数据表中,这种映射关系是通过ActiveRecord实现的。所以数据表中的字段名就是模型对象中的属性名,不再需要用名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - -
7、 - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 19 页 - - - - - - - - - XML 配置描述了。view: 视图,etmvc 支持多种视图, 甚至一个 action 多视图,最常用的视图是JspView,在 AJAX 应用中是JsonView,下载处理二进制数据时是BinaryView ,等等。七、 Hello,World 之旅OK,现在我们开始Hello,World 之旅,请参阅Hello,World 经典示例 。关于 etmvc 的配置etmvc 遵循 “ 约定优于配置 ” 的原则,通过文件的命名及存放位置来代替显式的配置,避免
8、编写烦杂的 XML 配置文件。etmvc 的配置只有一处,即在web.xml 中配置一个filter ,如下所示:源码复制打印etmvc com.et.mvc.DispatcherFilter controllerBasePackagecontrollers viewBasePath/views pluginplugin.OcrServer名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 19 页 - - - - - - - - - etmvc /* 其中, filter
9、的初始参数有三个:controllerBasePackage, viewBasePath, plugin ,说明如下:1、controllerBasePackage 是控制器的基包名称,如controllers ,所有的控制器类必须在controllers 包中,或者在controllers 的子包中。控制器类必须以Controller 结尾,必须继承Controller ,比如有如下的控制器类:源码复制打印package controllers; publicclass ArticleController extends ApplicationController public View s
10、howImage(int id) throws Exception /. public View download(int id) throws Exception /. publicvoid create() 控制器包名是controllers,控制器类名是ArticleController ,有 showImage 等 Action 方法。2、viewBasePath 是存放视图模板的位置,如下所示:视图模板的目录结构有一定的规则,在viewBasePath目录下是控制器名称(小写),再往下是对应每个Action 方法的视图文件。如ArticleController控制器中的方法creat
11、e 对应到/article/create.jsp 视图文件,即执行控制器的create方法后, etmvc 根据执行的结果找到对应的视图进行渲染。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 19 页 - - - - - - - - - 3、plugin 是插件的配置,一般情况下无须用到,所以不用配置该项,关于插件的使用留到后面的章节再作介绍。好了, etmvc 需要作的配置就这些,是不是很简单。Hello,World 经典示例我们利用etmvc 来建立一个Hello,
12、World 的 WEB 应用程序。一、首先,建立新的WEB 项目,引入et-mvc.jar 和 paranamer-1.3.jar,配置 web.xml,加入一个过滤器,如下所示:源码复制打印etmvc com.et.mvc.DispatcherFilter controllerBasePackagecontrollers viewBasePath/viewsetmvc /* 我们看到,过滤器com.et.mvc.DispatcherFilter目前只有二个参数,controllerBasePackage 指的是控制器的包名,viewBasePath 指的是视图模板的存放目录。二 、 接 下
13、来 , 我 们 开 始 编 写 控 制 器HelloController , 一 般 我 们 会 编 写 控 制 器 基 类ApplicationController , 我们的 HelloController 会继承它。 注意到,控制器的包名是controllers,这就是前面配置中的controllerBasePackage 配置值。源码复制打印package controllers; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 19 页 - - - - - -
14、- - - import com.et.mvc.Controller; publicclass ApplicationController extends Controller 源码复制打印package controllers; import com.et.mvc.TextView; publicclass HelloController extends ApplicationController public TextView say() returnnew TextView(hello,world); 三、至 些 , 我 们 的Hello,World程 序 编 写 完 毕 , 部 署 后
15、 在 浏 览 器 地 址 栏 输 入http:/localhost:8080/helloworld/hello/say,将会输出hello,world 字样。理解并使用控制器我们举个简单的例子说明一下从浏览器发送请求到服务器处理完请求返回信息给浏览器的过程。1、浏览器发出http:/localhost:8084/myweb/user/list这个请求,服务器将从这个URL 分析出如下信息:myweb:上下文路径信息User:控制器信息list:动作信息2、服务器根据这个信息查找控制器UserController 中的 list 方法,并执行之。3、服务器将查找名称是list.jsp 的视图并将
16、处理结果传递到视图,完成渲染过程。整个处理过程简单来说就是这样。每个请求都会创建新的控制器实例,控制器的类名必须以Controller结尾,必须继承Controller 类,比如 ApplicationController, HelloController等,控制器的 Action 方法允许继承,名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 19 页 - - - - - - - - - 我们一般都会创建一个根控制器,然后让其他控制器统一继承这个根控制器。每个控制器允许有
17、多个Action 操作,这些操作将映射到相应的URL 上。比如有如下的控制器:源码复制打印publicclass UserController extends ApplicationController publicvoid create() public View save(User user) throws Exception publicvoid login(String name, String password) throws Exception publicvoid logout() throws Exception 将相应的 URL 映射到控制器的Action 方法上:URLAc
18、tion 方法/user/create create /user/save save /user/login login /user/logout logout 至此,我们看到编写控制器处理WEB 请求就是这样简单。控制器的 Action 方法接受不同的参数,这些参数将自动绑定到Request 的参数, 方法可以返回不同的类型,比如void, String, JsonView, BinaryView等, etmvc 将据此确定处理后以何种视图返回。下面我们以一个用户登录的例子来说明控制器的一般用法:1、建立控制器,如下所示:源码复制打印package controllers; publiccl
19、ass UserController extends ApplicationController publicvoid login() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 19 页 - - - - - - - - - publicString handleLogin(String username, String password) throwsException return 你输入的用户: + username + 密码: + password; 我们定义
20、了二个Action方法,一个是login ,该方法返回值是void,系统默认将寻找/views/user/login.jsp 的视图进行显示,另一个是 handleLogin ,该方法将简单地将用户登录信息显示出来。2、我们来建立login.jsp 视图:源码复制打印form action= method=POST用户名: 密码: 我们看到FORM 中的 action 的 URL 指向,这个URL 将映射到我们控制器中的handleLogin方法,而该方法将返回String 类型, etmvc 将其解释了文本视图,所以将会在浏览器上显示登录的信息。启动浏览器,在地址栏上输入http:/loca
21、lhost:8080/test1/user/login ,将显示如下页面:输入用户名、密码然后点击提交按键,将显示:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 19 页 - - - - - - - - - Action 方法和控制器环境当请求到达时,etmvc 将创建控制器对象,控制器对象会查找与“ 被请求的action ”同名的public 实例方法。 如此看来, 控制器的 Action 方法是允许被继承的。如果你希望某些方法不被作为 action 调用,可以将其声
22、明为protected 或者 private。比如有如下的控制器:源码复制打印publicclass BlogController extends ApplicationController public String show() return show method; protected String create() return create method; 当访问 /blog/show时将输入框“show method” ,而访问 /blog/create 时将有 “ The requested resource (/test1/blog/create) is not availab
23、le ” 的信息。Action 方法允许使用控制器环境提供的一些对象:request response session servletContext controllerPath controllerName actionPath flash exception 他们的作用应该不言自明,其中flash 对象有使用方法我们将分出一个主题专门作介绍。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 19 页 - - - - - - - - - 关于 etmvc 的视图我们来探讨
24、etmvc 如何使用视图, 前面关于 “Action方法 ” 的介绍中我们提到,每个请求将会映射到一个Action 方法。 etmvc 将根据 Action 方法的返回类型来决定使用何种视图,大体有以下三种:返回 void 时将使用JSP视图。返回 String 时将字符串直接输出至浏览器。返回 View 或其子类时将使用对应的视图。下面我们来分别说明,如有如下的action 方法:源码复制打印publicclass UserController extends ApplicationController publicvoid test1() request.setAttribute(hell
25、o, hello,test1); action 方法 “test1”的返回类型是void ,这时etmvc 将其解释为JSP 视图,将会查找/views/user/test1.jsp 的文件,文件内容:源码复制打印Hello World!$hello运行 http:/localhost:8080/test2/user/test1 将会输出 “hello,test1”。我们来编写返回类型是String 的 action 方法:源码复制打印publicclass UserController extends ApplicationController public String test2() r
26、eturn hello,test2; 这时会将返回字符串“hello,test2”直接输出至浏览器。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 19 页 - - - - - - - - - 如果返回类型是View 或其子类型,则etmvc 会使用其定义的视图,如下所示:源码复制打印publicclass UserController extends ApplicationController public JspView test3() JspView view =
27、 new JspView(); view.setAttribute(hello, hello,test3); return view; public JspView test4() JspView view = new JspView(/common/other.jsp); view.setAttribute(hello, hello,test4); return view; 上面例子中test3使用默认的JSP视图位置和目录/user/test3.jsp,而 test4使用指定的视图位置和目录 /common/other.jsp。我们现来看个JsonView 的例子, JsonView 能够
28、处理多种数据结构,能够将其正确地转换成客户端需要的JSON 串,这在 AJAX 的开发中非常有用,同EXTJS 整合时也会很容易,如下所示:源码复制打印publicclass UserController extends ApplicationController public JsonView test5() Map result = new HashMap(); result.put(success, true ); result.put(msg, hello,test5); JsonView view = new JsonView(result); view.setContentType
29、(text/html;charset=utf-8);/允许指定 ContentType return view; 上面例子运行结果将向浏览器输出msg:hello,test5,success:true。我们来总结一下,etmvc 目前支持的视图包括:JspView TextView FreeMarkerView 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 19 页 - - - - - - - - - BinaryView JsonView ORM-ActiveRec
30、ord 基础etmvc 中访问数据可以使用JDBC,HIBERNA TE 等,鉴于JDBC 的烦琐和HIBERNATE的复杂,我们同时提供了一个ORM 的简易实现版本ActiveRecord 。在大多数中小型WEB 系统中,使用 ActiveRecord 就足够了。1、 使用前须将et-ar.jar, asm.jar, cglib.jar 等包引入项目, 然后进行配置activerecord.properties:domain_base_class=com.et.ar.ActiveRecordBase com.et.ar.ActiveRecordBase.driver_class=com.my
31、sql.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=2 在上面配置中我们配置了MYSQL数据库连接,配置文件activerecord.properties放在CLASSPATH 能找到的地方就好。2、我们来建立一张数据表:源码复制打印createtabl
32、e users( id intprimarykey auto_increment, name varchar(10) default null, addr varchar(50) default null, email varchar(50) default null, remark varchar(50) default null ) 然后建立对应的域对象:源码复制打印Table(name=users) publicclass User extends ActiveRecordBase 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - -
33、- - 名师精心整理 - - - - - - - 第 12 页,共 19 页 - - - - - - - - - Id private Integer id; Column private String name; Column private String addr; Column private String email; Column private String remark; /get,set. 我们的域模型对象继承自ActiveRecordBase ,到些, ORM 就建立完成了,我们看到,不需要复杂的配置文件,仅用几个简单的注解就完成了。3、基本的CRUD 操作增加记录:源码复制
34、打印User user = new User(); user.setName(name1); user.setAddr(addr1); user.setEmail(); user.save(); 修改记录:源码复制打印User user = User.find(User.class , 3); user.setRemark(user remark); user.save(); 删除记录:源码复制打印User user = User.find(User.class , 3); user.destroy(); 查询记录:源码复制打印List users = User.findAll(User.cl
35、ass ); for (User user: users) System.out.println(user.getName(); 条件查询:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 19 页 - - - - - - - - - 源码复制打印List users = User.findAll(User.class , addr like ?, new Object%百花路 %); for (User user: users) System.out.println(u
36、ser.getName(); 我们看到,借助ActiveRecord ,操作数据是如此容易。ActiveRecord 中同时访问多个数据库我们先来看一下ActiveRecord (下简称AR)的基本配置:源码复制打印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.
37、username=root com.et.ar.ActiveRecordBase.password=soft123456 com.et.ar.ActiveRecordBase.pool_size=2 其中的配置项domain_base_class 是我们域模型对象的基类,我们在定义模型类时必须让其继承 ActiveRecordBase, AR 将根据此找到对应的数据库连接。如果我们想同时使用多个数据库,这时我们可以先定义二个基类:源码复制打印publicclass Base1 extends ActiveRecordBase publicclass Base2 extends ActiveRe
38、cordBase 然后进行配置:源码复制打印domain_base_class=models.Base1 models.Base2 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 19 页 - - - - - - - - - models.Base1.driver_class=com.mysql.jdbc.Driver models.Base1.url=jdbc:mysql:/localhost/mydb1 models.Base1.username=root mode
39、ls.Base1.password=soft123456 models.Base1.pool_size=2 models.Base2.driver_class=com.mysql.jdbc.Driver models.Base2.url=jdbc:mysql:/localhost/mydb2 models.Base2.username=root models.Base2.password=soft123456 models.Base2.pool_size=2 我们只要让我们的模型类继承Base1或 Base2,就能正确使用对应的数据库连接。如果那一天又要改回去连接一个数据库了,只要改一下这个a
40、ctiverecord.properties 属性文件就OK 了。AR 中同时访问多个数据库时是不是很简单。ActiveRecord 中的关联我们在 ActiveRecord (下简称AR )中提供一对一、一对多、多对一等关联,分述如下:1、一对多: 一对多关联是指一个类(比如 Author)拥有另一个类 (比如 Book)的多个实例,用HashMany 注解描述:源码复制打印Table(name=authors) publicclass Author extends ActiveRecordBase Id private Integer id; Column private String n
41、ame; HasMany(foreignKey=authorId, dependent=DependentType.DELETE, order=id) private List books; /get,set. 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 19 页 - - - - - - - - - 源码复制打印Table(name=books) publicclass Book extends ActiveRecordBase Id private Integer
42、 id; Column private Integer authorId; Column private String name; BelongsTo(foreignKey=authorId) private Author author; /get,set. HasMany 有几个属性:foreignKey 指定多方的外键,必须指定。dependent指定在删除主表时做何操作,可选。有 DELETE ,DESTROY ,NULLIFY ,DELETE 是简单的删除从表记录;DESTROY 是再以级联的方式销毁从表对应的对象,如果这种级联关系有二级以上,则使用DESTROY 会比较合适;NULL
43、IFY是将从表的外键置为 NULL 值而并不删除。order 指定获取从表对应的记录时的排序字段,可选。2、一对一:一对一是一对多的特例,使用HasOne 描述,如:源码复制打印Table(name=authors) publicclass Author extends ActiveRecordBase Id private Integer id; Column private String name; HasOne(foreignKey=authorId) private Book book; /get,set. HasOne 注解的其他用法同HasMany。3、多对一:是指一个类属于另一个
44、类,比如上面的Book 类,使用 BelongsTo 注解描述多对一关系。好了, 定义了模型对象之间的关联之后,我们的编码简单了很多,比如我们要访问某个作者所拥有的图书,可以这样写:源码复制打印名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 19 页 - - - - - - - - - Author author = Author.find(Author.class , 1); List books = author.getBooks(); for (Book book
45、: books) System.out.println(book.getName(); AR 会维护对象之间的关联,在级联保存、删除及更新操作中都能保证在一个事务中,要么全部成功,要么全部失败。比如我们想删除某个作者及其拥有的图书记录,可以这样写:源码复制打印Author author = Author.find(Author.class , 1); author.destroy(); 建立一个新的Author 对象及其对应的Book 对象集合,并同时保存进数据库,可以这样写:源码复制打印Author author = new Author(); author.setName(author1)
46、; List books = new ArrayList(); for ( int i=0; i3; i+) Book book = new Book(); book.setName(book + i); books.add(book); author.setBooks(books); author.save(); 我们看到, AR 帮我们做了大部分工作,她会记住对象之间的关联并试图维护这种关系。当然,实际情况很复杂,但AR 能够完成大多数的工作etmvc 和 extjs 结合分页例子分页是每个WEB 应用程序必不可少的一环,数据量一大,就需要分页。分页需要前后台的配合才能完成,extjs 的
47、分页是由分页工具栏PagingToolbar 完成的,而etmvc 中的分页由ActiveRecord 完成。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 19 页 - - - - - - - - - 我们以显示用户资料为例子来看分页是怎么做的,建立一个分页的UserGrid,我们选择继承Ext.grid.GridPanel ,这样形成的Component 是可以复用的。来看看代码:源码复制打印UserGrid = Ext.extend(Ext.grid.GridPa
48、nel, initComponent:function() var ds = new Ext.data.JsonStore( url:user/getUsers, fields:id,name,addr,email,remark, root:users, id:id, totalProperty:total ); ds.load( params:start:0,limit:20 ); Ext.apply(this, title:用户资料管理 , store:ds, columns: header:名称 ,dataIndex:name,width:100, header:地址 ,dataInde
49、x:addr,width:200, header:邮箱 ,dataIndex:email,width:200, header:备注 ,dataIndex:remark,width:300 , bbar:new Ext.PagingToolbar( store:ds, pageSize:20 ) ); UserGrid.superclass.initComponent.call(this); ); 我们看到,分页时的JsonStore比不分页时增加了三个属性:root, id, totalProperty 。现在来看看后台的控制器代码:源码复制打印publicclass UserControll
50、er extends ApplicationController public JsonView getUsers(int start, int limit) throws Exception long total = User.count(User.class , null, null); List users = User.findAll(User.class, null, null, id, limit, start); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页