`
pangwu86
  • 浏览: 115839 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于Nutz与ExtJs的快速开发

    博客分类:
  • nutz
 
阅读更多

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

 

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

 

生成后的代码:

 

后台代码

 

 

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

 

model层

 

User.java

 

 

package org.nutz.demo3.model.admin;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Name;
import org.nutz.dao.entity.annotation.Table;

@Table("user")
public class User {

	@Id
	private long id;

	@Column
	private String name;

	@Column
	private int age;

	@Column
	private Date birthday;

	@Column
	private String phone;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}


}
 

 

Srevice层

 

UserService.java

 

 

package org.nutz.demo3.service.admin;

import com.geor.nutz.common.service.EntityService;
import org.nutz.demo3.model.admin.User;

public interface UserService extends EntityService<User> {

}

 

 

UserServiceImpl.java

 

 

package org.nutz.demo3.service.impl.admin;

import com.geor.nutz.common.service.impl.EntityServiceImpl;
import org.nutz.demo3.model.admin.User;
import org.nutz.demo3.service.admin.UserService;

public class UserServiceImpl extends EntityServiceImpl<User> implements UserService {

}
 

 

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

 

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

 

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

 

Action层

 

UserAction.java

 

 

package org.nutz.demo3.action.admin;

import javax.servlet.http.HttpServletRequest;

import org.nutz.ioc.annotation.InjectName;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Param;

import com.geor.nutz.extjs.action.ExtEntityAction;
import org.nutz.demo3.model.admin.User;
import org.nutz.demo3.service.admin.UserService;


@InjectName("UserAction")
@At("/admin/user")
public class UserAction extends ExtEntityAction<UserService, User> {

	public void needCombobox() {
		// TODO Auto-generated method stub
	}

	public Object fetch(@Param("..") User entity, HttpServletRequest request) {
		// TODO Auto-generated method stub
		return null;
	}

	@At()
	public Object insert(@Param("..") User entity, HttpServletRequest request) {
		return getService().insert(entity);
	}

	@At()
	public Object update(@Param("..") User entity, HttpServletRequest request) {
		return getService().update(entity);
	}

	@At()
	public Object delete(@Param("..") User entity, HttpServletRequest request) {
		return getService().delete(entity);
	}

	@At()
	public Object save(@Param("entities") User[] entities, HttpServletRequest request) {
		return getService().save(entities);
	}

}

 

 

这里会继承一个ExtEntityAction

 

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

 

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

 

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

 

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

 

 

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

 

Entrance.java

 

 

package org.nutz.demo3.action;

import org.nutz.mvc.annotation.Fail;
import org.nutz.mvc.annotation.IocBy;
import org.nutz.mvc.annotation.Modules;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Views;
import org.nutz.mvc.ioc.provider.JsonIocProvider;

import com.geor.nutz.extjs.view.ExtViewMaker;

/**
 * 系统入口。
 * 
 * @author pangwu86@gmail.com
 * 
 */
@IocBy(type = JsonIocProvider.class, args = { "/action.js", "/aop.js" })
@Modules(scanPackage = true)
@Views(ExtViewMaker.class)
@Ok("ext")
@Fail("ext")
public class Entrance {
}
 

 

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

 

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

 

 

@Modules(scanPackage = true)

 

 

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

 

 

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

 

Service.js

 

 

/**
 * 服务。
 */
var services = {

	UserService : {
		type : 'org.nutz.demo3.service.impl.admin.UserServiceImpl',
		singleton : false
	}


}

 

 

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

 

Action.js

 

 

/**
 * 
 * @type 
 */
var actions = {

	UserAction : {
		type : "org.nutz.demo3.action.admin.UserAction",
		singleton : false,
		scope : "session"
	}


}

 

 

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

 

Aop.js

 

 

/**
 * AOP的定义与规则。
 * 
 * @type
 */
var aop = {
	/**
	 * 记录日志。
	 * 
	 * @type
	 */
	log : {
		type : 'com.geor.nutz.common.aop.LogAop'
	},
	/**
	 * 声明式事务。
	 * 
	 * @type
	 */
	trans : {
		type : 'com.geor.nutz.common.aop.TransAop'
	},
	/**
	 * aop规则。
	 * 
	 * @type
	 */
	$aop : {
		type : 'org.nutz.ioc.aop.config.impl.JsonAopConfigration',
		fields : {
			itemList : [
					['org\.nutz\.demo3\.action\..+\..+', '(insert|update|delete|clear|save)', 'ioc:log'],
					['org\.nutz\.demo3\.action\..+\..+', '(insert|update|delete|clear|save)', 'ioc:trans']
			]
		}
	}

};

 

 

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

 

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

 

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

 

Jdbc.js

 

 

/**
 * JDBC配置信息。
 * 
 * @type
 */
var jdbc = {
	dataSource : {
		type : "com.mchange.v2.c3p0.ComboPooledDataSource",
		events : {
			depose : 'close'
		},
		fields : {
			driverClass : 'com.mysql.jdbc.Driver',
			jdbcUrl : 'jdbc:mysql://localhost:3306/nutz',
			user : 'root',
			password : 'toor'
		}
	}
};
 

 

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

 

log4j.properties 

 

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

 

 

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

 

web.xml

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
	<display-name>Demo3</display-name>
	<!-- filter定义 -->
	<filter>
		<filter-name>entrance</filter-name>
		<filter-class>org.nutz.mvc.NutFilter</filter-class>
		<init-param>
			<param-name>modules</param-name>
			<param-value>org.nutz.demo3.action.Entrance</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>entrance</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- listener定义 -->
	<listener>
		<listener-class>org.nutz.mvc.NutSessionListener</listener-class>
	</listener>
	<!-- 首页 -->
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
</web-app>
 

 

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

 

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

 

 

前台代码

 

 

 

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

 

来看一下生成页面文件

 

user.jsp

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户管理</title>
<link rel='stylesheet' type='text/css' href='../../js/resources/css/ext-all.css'/>
<link rel='stylesheet' type='text/css' href='../../js/resources/css/ext-patch.css' />
<link rel='stylesheet' type='text/css' href='../../js/xExt/xExt.css' />
<script type='text/javascript' src='../../js/ext-base.js'></script>
<script type='text/javascript' src='../../js/ext-all.js'></script>
<script type='text/javascript' src='../../js/ext-lang-zh_CN.js'></script>
<script type='text/javascript' src='../../js/xExt/xExt-base.js'></script>
<script type='text/javascript' src='../../js/xExt/xExt.js'></script>
<script type='text/javascript' src='../../js/s.js'></script>
<script type='text/javascript' src='user.js'></script>
</head>
<body>
	<div id='userDiv' style='width:100%;height:100%;'></div>
</body>
</html>

 

 

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

 

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

 

 

user.js

 

 

Ext.onReady(function() {

			// xExt式样初始化(路径设定,默认当前为二级目录)
			xExt.css.init();

			// 配置Grid
			var gridConfig = xExt.grid.GridConfig({
						// 工程名称
						webroot : 'Demo3',
						// 主模块名称
						mainModule : 'admin',
						// 子模块名称
						subModule : 'user',
						// 列相关信息
						columns : [{
									name : 'id',
									type : 'int',
									header : '编号',
									hidden : true,
									filterable : false,
									sortable : false
								}, {
									name : 'name',
									type : 'string',
									header : '用户名称',
									hidden : false,
									filterable : true,
									sortable : true
								}, {
									name : 'age',
									type : 'int',
									header : '年龄',
									hidden : false,
									filterable : true,
									sortable : true
								}, {
									name : 'birthday',
									type : 'date',
									header : '生日',
									hidden : false,
									filterable : true,
									sortable : true
								}, {
									name : 'phone',
									type : 'string',
									header : '电话',
									hidden : false,
									filterable : true,
									sortable : true
								}],

						queryMode : 1,

						editableGrid : false,

						basicGridConfig : {
							// 新建按钮
							needInsertButton : true,
							// 窗口控件
							insertFormItems : [{
										xtype : 'fieldset',
										title : '基本信息',
										layout : 'form',
										style : xExt.css.fieldset.margins_7px,
										defaults : {
											width : xExt.css.form.fieldWidth
										},
										items : [{
													xtype : 'hidden',
													fieldLabel : '编号',
													name : 'id'
												}, {
													xtype : 'textfield',
													fieldLabel : '用户名称',
													name : 'name',
													allowBlank : true,
													maxLength : 50
												}, {
													xtype : 'numberfield',
													fieldLabel : '年龄',
													name : 'age',
													allowBlank : true,
													maxLength : 50
												}, {
													xtype : 'datefield',
													fieldLabel : '生日',
													name : 'birthday',
													allowBlank : true,
													maxLength : 50,
													format : 'Y-m-d'
												}, {
													xtype : 'textfield',
													fieldLabel : '电话',
													name : 'phone',
													allowBlank : true,
													maxLength : 50
												}]
									}],
							// 更新按钮
							needUpdateButton : true,
							// 窗口控件
							updateFormItems : [{
										xtype : 'fieldset',
										title : '基本信息',
										layout : 'form',
										style : xExt.css.fieldset.margins_7px,
										defaults : {
											width : xExt.css.form.fieldWidth
										},
										items : [{
													xtype : 'hidden',
													fieldLabel : '编号',
													name : 'id'
												}, {
													xtype : 'textfield',
													fieldLabel : '用户名称',
													name : 'name',
													allowBlank : true,
													maxLength : 50
												}, {
													xtype : 'numberfield',
													fieldLabel : '年龄',
													name : 'age',
													allowBlank : true,
													maxLength : 50
												}, {
													xtype : 'datefield',
													fieldLabel : '生日',
													name : 'birthday',
													allowBlank : true,
													maxLength : 50,
													format : 'Y-m-d'
												}, {
													xtype : 'textfield',
													fieldLabel : '电话',
													name : 'phone',
													allowBlank : true,
													maxLength : 50
												}]
									}],
							// 删除按钮
							needDeleteButton : true,
							// 批量删除按钮
							needClearButton : true
						},

						// 默认双击事件,弹出更新窗口(在有更新窗口的前提下)
						listeners : {
							rowdblclick : true
						}

					});

			// 生成Grid
			var dataGrid = xExt.grid.GridPanel(gridConfig);

		});

 

 

 

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

 

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

 

 

// 新建按钮
needInsertButton : true,

 

 

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

 

 

 

总结

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

 

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

 

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

 

 

 

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

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

 

2
0
分享到:
评论
1 楼 lufazhi 2016-03-07  
楼主,是否可以将源码分享,谢谢,小弟初次接触nutz不太理解,想尽快学习,谢谢!

相关推荐

    NutzWk是基于Nutz的Java开源企业级开发框架.rar

    基于Nutz的开源企业级开发框架 NutzWk 3.x 运行环境: JDK 8 Tomcat 8 Maven 3.3.9 Nutz v1.r.58 NutzWk 3.x 新特性: 集成Shiro权限框架 集成Ehcache缓存 集成Redis 支持语言国际化 支持注解式事务 ...

    Nutz+ExtJS示例教程——后台Service实现

    NULL 博文链接:https://pangwu86.iteye.com/blog/911090

    nutz框架开发手册

    nutz框架开发手册,框架很方便使用的,和大家分享

    高效,小巧的开源JAVA WEB 开发框架-Nutz (源码,开发文档)

    不依赖任何第三方 Jar 包,从而便于程序员建立开发环境,部署,甚至重新编译 Nutz 的源代码。 不幸的是在第一版,我还是依赖了 Javassist 可以很好的和各种主流框架和类库等协同工作 你可以组合 Nutz.Dao + Spring ...

    Nutz高效开发框架v1.0.5免费版

    Nutz高效开发框架是国内比较独立强大的技术团队开发的轻量级的框架快捷实用工具,由于可以方便地在各种数据库中调用存储数据,所以可以称之为方便程序员通行的项目大厦的手脚架工具。对于从事数据库相关的程序员来说...

    基于Nutz和BuguMongodb的,使用Mongodb作为持久层的Issue管理系统.zip

    基于node.js、vue、mongodb等技术构建的web系统,界面美观,功能齐全,适合用作毕业设计、课程设计作业等,项目均经过测试,可快速部署运行! 基于node.js、vue、mongodb等技术构建的web系统,界面美观,功能齐全,...

    nutz微信应用开发项目nuby.zip

    Nutz easyui mpsdk4j 七牛云服务微信应用开发项目 1. 实现微信基本的消息互动功能,菜单响应,用户信息同步等 2. 最新的JSSDK功能,如分享,图片上传, 网页授权, 一键关注等 ...

    nutz 使用手册 nutz-1.a.33-manual.pdf

    nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册

    nutz框架使用手册.zip

    nutz框架使用手册,从零到有深入学习nutz平台开发

    nutz插件 定位页面路径

    可以快速定位路径 页面 本jar包是nutz实用插件 希望大家多多下载

    Nutz开发用到的jar包

    NULL 博文链接:https://jackaney.iteye.com/blog/973561

    nutz邮箱验证jar包

    用于nutz邮箱验证jar包

    nutz搭建的MVC框架

    用开源框架nutz搭建的MVC框架,适合小型系统的开发,快捷方便!

    nutz生成javabean工具.zip

    nutz生成javabean工具.zip

    nutz代码生成器

    可连接多种数据库根据表直接生成nutz所需的bean

    Nutz官方手册

    Nutz, 它是一组轻便小型的框架的集合, 各个部分可以被独立使用。 而 Nutz 的目标就是在力所能及的...希望通过 Nutz, Java 的开发人员可以获得更快的开发速度,更少的代码量,并且这些以不损害运行时效率为前提。

    Nutz-1.b.38

    Spring 里采用 Nutz.Dao ,又比如在 Nutz.Ioc 里使用 Hibernate 等整 -- 它所有功能均不依赖第三方 jar 文件。这就意味着:如果一个 Web 应用,你在 WEB-INF/lib 下只 需要放置一个 nutz.jar 就够了当然你要使用其它...

    nutz-1.b.52.zip

    Aop -- 轻便快速的切面编程支持 Plugin -- 轻便的插件机制 Resource -- 资源扫描 它所有的功能均不依赖第三方 jar 包 这就意味着: 如果一个 Web 应用,你在 WEB-INF/lib 下只 需要放置一个 nutz.jar 就够了 当然你...

    Nutz框架文档

    对于 Java 程序员来说,除 SSH 之外,可能还有另外一个选择: Nutz 当然,它是开源的,并且是完全免费的。 同传统的 SSH 相比,它具备如下特点: 轻 -- 当前最新版,整个 jar 文件共 820k 薄 -- 针对 JDBC 的薄封装...

Global site tag (gtag.js) - Google Analytics