分享

基于Nutz与ExtJs的快速开发

 飞鹰飞龙飞天 2014-09-21

这里对Nutz与ExtJs都进行二次封装,使前后台代码尽可能的复用,大部分操作都是在基类中完成的。

 

使用过程请看附件中的视频。

 

生成后的代码:

 

后台代码

 

 

分别在src目录下生产了java代码,在resource目录下生成了nutz的配置文件。

 

model层

 

User.java

 

 

Java代码  收藏代码
  1. package org.nutz.demo3.model.admin;  
  2.   
  3. import java.util.Date;  
  4. import java.util.List;  
  5. import java.util.Set;  
  6.   
  7. import org.nutz.dao.entity.annotation.Column;  
  8. import org.nutz.dao.entity.annotation.Id;  
  9. import org.nutz.dao.entity.annotation.Name;  
  10. import org.nutz.dao.entity.annotation.Table;  
  11.   
  12. @Table("user")  
  13. public class User {  
  14.   
  15.     @Id  
  16.     private long id;  
  17.   
  18.     @Column  
  19.     private String name;  
  20.   
  21.     @Column  
  22.     private int age;  
  23.   
  24.     @Column  
  25.     private Date birthday;  
  26.   
  27.     @Column  
  28.     private String phone;  
  29.   
  30.     public long getId() {  
  31.         return id;  
  32.     }  
  33.   
  34.     public void setId(long id) {  
  35.         this.id = id;  
  36.     }  
  37.   
  38.     public String getName() {  
  39.         return name;  
  40.     }  
  41.   
  42.     public void setName(String name) {  
  43.         this.name = name;  
  44.     }  
  45.   
  46.     public int getAge() {  
  47.         return age;  
  48.     }  
  49.   
  50.     public void setAge(int age) {  
  51.         this.age = age;  
  52.     }  
  53.   
  54.     public Date getBirthday() {  
  55.         return birthday;  
  56.     }  
  57.   
  58.     public void setBirthday(Date birthday) {  
  59.         this.birthday = birthday;  
  60.     }  
  61.   
  62.     public String getPhone() {  
  63.         return phone;  
  64.     }  
  65.   
  66.     public void setPhone(String phone) {  
  67.         this.phone = phone;  
  68.     }  
  69.   
  70.   
  71. }  
 

 

Srevice层

 

UserService.java

 

 

Java代码  收藏代码
  1. package org.nutz.demo3.service.admin;  
  2.   
  3. import com.geor.nutz.common.service.EntityService;  
  4. import org.nutz.demo3.model.admin.User;  
  5.   
  6. public interface UserService extends EntityService<User> {  
  7.   
  8. }  

 

 

UserServiceImpl.java

 

 

Java代码  收藏代码
  1. package org.nutz.demo3.service.impl.admin;  
  2.   
  3. import com.geor.nutz.common.service.impl.EntityServiceImpl;  
  4. import org.nutz.demo3.model.admin.User;  
  5. import org.nutz.demo3.service.admin.UserService;  
  6.   
  7. public class UserServiceImpl extends EntityServiceImpl<User> implements UserService {  
  8.   
  9. }  
 

 

可以看到这里的Service层代码非常简洁(ME觉得已经不能再简洁了,这里可是一行代码都木有呀!),常用的增删改查功能,已经在基类中实现了。

 

Nutz本身就提供了类似EntityService这样的基类,大家也可以去看看。

 

这里是觉得自己封装的更加顺手些,并加入了一些Nutz本身没有提供的特性,大家可以仿照Nutz提供的基类,在自己需求的基础上来实现自己的基类。

 

Action层

 

UserAction.java

 

 

Java代码  收藏代码
  1. package org.nutz.demo3.action.admin;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4.   
  5. import org.nutz.ioc.annotation.InjectName;  
  6. import org.nutz.mvc.annotation.At;  
  7. import org.nutz.mvc.annotation.Param;  
  8.   
  9. import com.geor.nutz.extjs.action.ExtEntityAction;  
  10. import org.nutz.demo3.model.admin.User;  
  11. import org.nutz.demo3.service.admin.UserService;  
  12.   
  13.   
  14. @InjectName("UserAction")  
  15. @At("/admin/user")  
  16. public class UserAction extends ExtEntityAction<UserService, User> {  
  17.   
  18.     public void needCombobox() {  
  19.         // TODO Auto-generated method stub  
  20.     }  
  21.   
  22.     public Object fetch(@Param("..") User entity, HttpServletRequest request) {  
  23.         // TODO Auto-generated method stub  
  24.         return null;  
  25.     }  
  26.   
  27.     @At()  
  28.     public Object insert(@Param("..") User entity, HttpServletRequest request) {  
  29.         return getService().insert(entity);  
  30.     }  
  31.   
  32.     @At()  
  33.     public Object update(@Param("..") User entity, HttpServletRequest request) {  
  34.         return getService().update(entity);  
  35.     }  
  36.   
  37.     @At()  
  38.     public Object delete(@Param("..") User entity, HttpServletRequest request) {  
  39.         return getService().delete(entity);  
  40.     }  
  41.   
  42.     @At()  
  43.     public Object save(@Param("entities") User[] entities, HttpServletRequest request) {  
  44.         return getService().save(entities);  
  45.     }  
  46.   
  47. }  

 

 

这里会继承一个ExtEntityAction

 

在这个基类中,有针对ExtJS的特点,进行了一些列的封装,因为在ExtJS中某些数据,需要使用特定的格式,所以这里只针对前台ExtJS的情况。

 

将来如果前台框架换了其他的,只需要仿照这个基类,做一个对应的就可以了。而Service层与model层的代码是不需要改动的。

 

可以看到,这里没有list方法(查询)与clear方法(批量删除),那是因为他们在方法入参没有自定义类型的情况下,可以抽共通,放到基类中。

 

而insert,update,delete等等方法,因为参数会自动转换为User类型,入参中必须使用这个自定义类型,所以实在是无法省略掉这部分代码,因为本人最初的想法也是将这一层做成像Service层一样,一行代码也没有...那样看起来是多么的爽呀(好吧,ME承认自己有点偏执了

 

 

oh,还有一个Nutz的入口函数,这是Nutz启动时的关键。

 

Entrance.java

 

 

Java代码  收藏代码
  1. package org.nutz.demo3.action;  
  2.   
  3. import org.nutz.mvc.annotation.Fail;  
  4. import org.nutz.mvc.annotation.IocBy;  
  5. import org.nutz.mvc.annotation.Modules;  
  6. import org.nutz.mvc.annotation.Ok;  
  7. import org.nutz.mvc.annotation.Views;  
  8. import org.nutz.mvc.ioc.provider.JsonIocProvider;  
  9.   
  10. import com.geor.nutz.extjs.view.ExtViewMaker;  
  11.   
  12. /** 
  13.  * 系统入口。 
  14.  *  
  15.  * @author pangwu86@gmail.com 
  16.  *  
  17.  */  
  18. @IocBy(type = JsonIocProvider.class, args = { "/action.js", "/aop.js" })  
  19. @Modules(scanPackage = true)  
  20. @Views(ExtViewMaker.class)  
  21. @Ok("ext")  
  22. @Fail("ext")  
  23. public class Entrance {  
  24. }  
 

 

这里会使用一个自定义View,是针对ExtJS封装的,大家不要问为什么哪里都有封装,如果不封装,不代码复用,生成的代码怎么可能会如此简洁来,代码复用确实是必须的。

 

其实@Ok("ext"),本质上还是@Ok("json"),只是针对ExtJS格式的特点做了一些特殊处理。

 

 

Java代码  收藏代码
  1. @Modules(scanPackage = true)  

 

 

这句话的作用就是扫描当前目录下的文件(包括子目录),发现有Action类的话,就会将其配置的路径信息加载,你在后面访问时,才会进去到对应的方法中。用了它,你就尽管在该目录下写action类吧,自动扫描会一个不拉的全部加载,不用在一个一个配置了。

 

 

有了上述代码,后台的就基本完成了,下面是配置文件的情况。

 

Service.js

 

 

Js代码  收藏代码
  1. /** 
  2.  * 服务。 
  3.  */  
  4. var services = {  
  5.   
  6.     UserService : {  
  7.         type : 'org.nutz.demo3.service.impl.admin.UserServiceImpl',  
  8.         singleton : false  
  9.     }  
  10.   
  11.   
  12. }  

 

 

这里用过IOC的都会明白,依赖注入,不解释了。

 

Action.js

 

 

Js代码  收藏代码
  1. /** 
  2.  *  
  3.  * @type  
  4.  */  
  5. var actions = {  
  6.   
  7.     UserAction : {  
  8.         type : "org.nutz.demo3.action.admin.UserAction",  
  9.         singleton : false,  
  10.         scope : "session"  
  11.     }  
  12.   
  13.   
  14. }  

 

 

这里本身其实可以不用Nutz的容器,但因为为了使用AOP做log输出与事务控制,这里所有的Action必须是在容器中的。

 

Aop.js

 

 

Js代码  收藏代码
  1. /** 
  2.  * AOP的定义与规则。 
  3.  *  
  4.  * @type 
  5.  */  
  6. var aop = {  
  7.     /** 
  8.      * 记录日志。 
  9.      *  
  10.      * @type 
  11.      */  
  12.     log : {  
  13.         type : 'com.geor.nutz.common.aop.LogAop'  
  14.     },  
  15.     /** 
  16.      * 声明式事务。 
  17.      *  
  18.      * @type 
  19.      */  
  20.     trans : {  
  21.         type : 'com.geor.nutz.common.aop.TransAop'  
  22.     },  
  23.     /** 
  24.      * aop规则。 
  25.      *  
  26.      * @type 
  27.      */  
  28.     $aop : {  
  29.         type : 'org.nutz.ioc.aop.config.impl.JsonAopConfigration',  
  30.         fields : {  
  31.             itemList : [  
  32.                     ['org\.nutz\.demo3\.action\..+\..+', '(insert|update|delete|clear|save)', 'ioc:log'],  
  33.                     ['org\.nutz\.demo3\.action\..+\..+', '(insert|update|delete|clear|save)', 'ioc:trans']  
  34.             ]  
  35.         }  
  36.     }  
  37.   
  38. };  

 

 

这种AOP的使用方式应该是Nutz中最简单却最强大好用(兽(又是屏蔽词)兽出品,必属精品)

 

Nutz本身也就提供了TransAop与LogAop,ME只是对其做了一下汉化与加入了点个性化东西,大家使用默认的即可。

 

可以看到只要通过一个牛X的正则表达式,你就可以对工程中你想aop的地方插一脚了,so easy!

 

Jdbc.js

 

 

Js代码  收藏代码
  1. /** 
  2.  * JDBC配置信息。 
  3.  *  
  4.  * @type 
  5.  */  
  6. var jdbc = {  
  7.     dataSource : {  
  8.         type : "com.mchange.v2.c3p0.ComboPooledDataSource",  
  9.         events : {  
  10.             depose : 'close'  
  11.         },  
  12.         fields : {  
  13.             driverClass : 'com.mysql.jdbc.Driver',  
  14.             jdbcUrl : 'jdbc:mysql://localhost:3306/nutz',  
  15.             user : 'root',  
  16.             password : 'toor'  
  17.         }  
  18.     }  
  19. };  
 

 

数据库连接,直接copy官方文档中的,nutz中有对常用的四种数据库连接池的写法,方便大家copy。

 

log4j.properties 

 

不贴代码了,没有意义,反正是帮你默认生成一个,如果有现成的,就不会再生成了。

 

 

后台代码还一个就是web.xml,新建工程里的web.xml只有首页信息,要加上nutz的配置信息才行。

 

web.xml

 

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns="http://java./xml/ns/javaee" xmlns:web="http://java./xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java./xml/ns/javaee http://java./xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
  3.     <display-name>Demo3</display-name>  
  4.     <!-- filter定义 -->  
  5.     <filter>  
  6.         <filter-name>entrance</filter-name>  
  7.         <filter-class>org.nutz.mvc.NutFilter</filter-class>  
  8.         <init-param>  
  9.             <param-name>modules</param-name>  
  10.             <param-value>org.nutz.demo3.action.Entrance</param-value>  
  11.         </init-param>  
  12.     </filter>  
  13.     <filter-mapping>  
  14.         <filter-name>entrance</filter-name>  
  15.         <url-pattern>/*</url-pattern>  
  16.     </filter-mapping>  
  17.     <!-- listener定义 -->  
  18.     <listener>  
  19.         <listener-class>org.nutz.mvc.NutSessionListener</listener-class>  
  20.     </listener>  
  21.     <!-- 首页 -->  
  22.     <welcome-file-list>  
  23.         <welcome-file>index.html</welcome-file>  
  24.         <welcome-file>index.htm</welcome-file>  
  25.         <welcome-file>index.jsp</welcome-file>  
  26.         <welcome-file>default.html</welcome-file>  
  27.         <welcome-file>default.htm</welcome-file>  
  28.         <welcome-file>default.jsp</welcome-file>  
  29.     </welcome-file-list>  
  30. </web-app>  
 

 

就是加入了org.nutz.mvc.NutFilter这个过滤器,拦截下所有的请求(/*)

 

然后通过上面配置的入口函数,进去到对应的Action中。

 

 

前台代码

 

 

 

前台代码,默认生成在page目录下,js目录下就是ExtJS的类库了,还有一个针对其部分空间二次封装的类库xExt。

 

来看一下生成页面文件

 

user.jsp

 

 

Jsp代码  收藏代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <title>用户管理</title>  
  8. <link rel='stylesheet' type='text/css' href='../../js/resources/css/ext-all.css'/>  
  9. <link rel='stylesheet' type='text/css' href='../../js/resources/css/ext-patch.css' />  
  10. <link rel='stylesheet' type='text/css' href='../../js/xExt/xExt.css' />  
  11. <script type='text/javascript' src='../../js/ext-base.js'></script>  
  12. <script type='text/javascript' src='../../js/ext-all.js'></script>  
  13. <script type='text/javascript' src='../../js/ext-lang-zh_CN.js'></script>  
  14. <script type='text/javascript' src='../../js/xExt/xExt-base.js'></script>  
  15. <script type='text/javascript' src='../../js/xExt/xExt.js'></script>  
  16. <script type='text/javascript' src='../../js/s.js'></script>  
  17. <script type='text/javascript' src='user.js'></script>  
  18. </head>  
  19. <body>  
  20.     <div id='userDiv' style='width:100%;height:100%;'></div>  
  21. </body>  
  22. </html>  

 

 

可以看到这里的代码也是非常简洁的,大部分是对js,css文件的导入。

 

body标签中只有一个div,生成的grid会绑定到该div上。

 

 

user.js

 

 

Js代码  收藏代码
  1. Ext.onReady(function() {  
  2.   
  3.             // xExt式样初始化(路径设定,默认当前为二级目录)  
  4.             xExt.css.init();  
  5.   
  6.             // 配置Grid  
  7.             var gridConfig = xExt.grid.GridConfig({  
  8.                         // 工程名称  
  9.                         webroot : 'Demo3',  
  10.                         // 主模块名称  
  11.                         mainModule : 'admin',  
  12.                         // 子模块名称  
  13.                         subModule : 'user',  
  14.                         // 列相关信息  
  15.                         columns : [{  
  16.                                     name : 'id',  
  17.                                     type : 'int',  
  18.                                     header : '编号',  
  19.                                     hidden : true,  
  20.                                     filterable : false,  
  21.                                     sortable : false  
  22.                                 }, {  
  23.                                     name : 'name',  
  24.                                     type : 'string',  
  25.                                     header : '用户名称',  
  26.                                     hidden : false,  
  27.                                     filterable : true,  
  28.                                     sortable : true  
  29.                                 }, {  
  30.                                     name : 'age',  
  31.                                     type : 'int',  
  32.                                     header : '年龄',  
  33.                                     hidden : false,  
  34.                                     filterable : true,  
  35.                                     sortable : true  
  36.                                 }, {  
  37.                                     name : 'birthday',  
  38.                                     type : 'date',  
  39.                                     header : '生日',  
  40.                                     hidden : false,  
  41.                                     filterable : true,  
  42.                                     sortable : true  
  43.                                 }, {  
  44.                                     name : 'phone',  
  45.                                     type : 'string',  
  46.                                     header : '电话',  
  47.                                     hidden : false,  
  48.                                     filterable : true,  
  49.                                     sortable : true  
  50.                                 }],  
  51.   
  52.                         queryMode : 1,  
  53.   
  54.                         editableGrid : false,  
  55.   
  56.                         basicGridConfig : {  
  57.                             // 新建按钮  
  58.                             needInsertButton : true,  
  59.                             // 窗口控件  
  60.                             insertFormItems : [{  
  61.                                         xtype : 'fieldset',  
  62.                                         title : '基本信息',  
  63.                                         layout : 'form',  
  64.                                         style : xExt.css.fieldset.margins_7px,  
  65.                                         defaults : {  
  66.                                             width : xExt.css.form.fieldWidth  
  67.                                         },  
  68.                                         items : [{  
  69.                                                     xtype : 'hidden',  
  70.                                                     fieldLabel : '编号',  
  71.                                                     name : 'id'  
  72.                                                 }, {  
  73.                                                     xtype : 'textfield',  
  74.                                                     fieldLabel : '用户名称',  
  75.                                                     name : 'name',  
  76.                                                     allowBlank : true,  
  77.                                                     maxLength : 50  
  78.                                                 }, {  
  79.                                                     xtype : 'numberfield',  
  80.                                                     fieldLabel : '年龄',  
  81.                                                     name : 'age',  
  82.                                                     allowBlank : true,  
  83.                                                     maxLength : 50  
  84.                                                 }, {  
  85.                                                     xtype : 'datefield',  
  86.                                                     fieldLabel : '生日',  
  87.                                                     name : 'birthday',  
  88.                                                     allowBlank : true,  
  89.                                                     maxLength : 50,  
  90.                                                     format : 'Y-m-d'  
  91.                                                 }, {  
  92.                                                     xtype : 'textfield',  
  93.                                                     fieldLabel : '电话',  
  94.                                                     name : 'phone',  
  95.                                                     allowBlank : true,  
  96.                                                     maxLength : 50  
  97.                                                 }]  
  98.                                     }],  
  99.                             // 更新按钮  
  100.                             needUpdateButton : true,  
  101.                             // 窗口控件  
  102.                             updateFormItems : [{  
  103.                                         xtype : 'fieldset',  
  104.                                         title : '基本信息',  
  105.                                         layout : 'form',  
  106.                                         style : xExt.css.fieldset.margins_7px,  
  107.                                         defaults : {  
  108.                                             width : xExt.css.form.fieldWidth  
  109.                                         },  
  110.                                         items : [{  
  111.                                                     xtype : 'hidden',  
  112.                                                     fieldLabel : '编号',  
  113.                                                     name : 'id'  
  114.                                                 }, {  
  115.                                                     xtype : 'textfield',  
  116.                                                     fieldLabel : '用户名称',  
  117.                                                     name : 'name',  
  118.                                                     allowBlank : true,  
  119.                                                     maxLength : 50  
  120.                                                 }, {  
  121.                                                     xtype : 'numberfield',  
  122.                                                     fieldLabel : '年龄',  
  123.                                                     name : 'age',  
  124.                                                     allowBlank : true,  
  125.                                                     maxLength : 50  
  126.                                                 }, {  
  127.                                                     xtype : 'datefield',  
  128.                                                     fieldLabel : '生日',  
  129.                                                     name : 'birthday',  
  130.                                                     allowBlank : true,  
  131.                                                     maxLength : 50,  
  132.                                                     format : 'Y-m-d'  
  133.                                                 }, {  
  134.                                                     xtype : 'textfield',  
  135.                                                     fieldLabel : '电话',  
  136.                                                     name : 'phone',  
  137.                                                     allowBlank : true,  
  138.                                                     maxLength : 50  
  139.                                                 }]  
  140.                                     }],  
  141.                             // 删除按钮  
  142.                             needDeleteButton : true,  
  143.                             // 批量删除按钮  
  144.                             needClearButton : true  
  145.                         },  
  146.   
  147.                         // 默认双击事件,弹出更新窗口(在有更新窗口的前提下)  
  148.                         listeners : {  
  149.                             rowdblclick : true  
  150.                         }  
  151.   
  152.                     });  
  153.   
  154.             // 生成Grid  
  155.             var dataGrid = xExt.grid.GridPanel(gridConfig);  
  156.   
  157.         });  

 

 

 

可以看到,这里并没有直接使用Ext里面的控件,而是针对这个增删改查页面的需求,封装到了xExt这个类库中。

 

调用xExt.grid.GridConfig生成配置信息后,调用 xExt.grid.GridPanel就可以生成Grid了。

 

 

Js代码  收藏代码
  1. // 新建按钮  
  2. needInsertButton : true,  

 

 

像这个新建按钮,只需要设置true,页面上就会多一个新增按钮,并会有一个弹出窗口,在窗口中可以添加新数据,省去了直接使用Ext生成按钮再生成窗口的一大段代码,总的来说,一样是遵循了代码复用的思想。

 

 

 

总结

以上代码都是使用代码生成工具生成的,可以看到,本人在遵循代码复用的基础上,尽可能的把共通代码提取出来,将变化的地方空出来,留给开发人员使用。生成的代码也基本具有可读性。

 

做这个代码生成工具的目的,算是对快速开发的一种尝试,Nutz项目中也有代码生成工具,只是目前貌似进度停止了,这里写的这个也是期望能起到一个抛砖引玉的作用,激发其大家的思考。

 

望Nutz的代码生成工具,早日Release。

 

 

 

***************************邪恶的分割线******************************

代码生成工具的原理,下次再讲

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多