`
pangwu86
  • 浏览: 117777 次
  • 性别: 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不太理解,想尽快学习,谢谢!

相关推荐

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

    5. **ExtJS与Nutz的交互** 在前端,我们可以使用ExtJS的Ajax组件,如`Ext.Ajax.request`,来发送HTTP请求到Nutz的Controller,获取Service处理后的数据。例如,我们可以创建一个ExtJS的按钮,点击时向服务器请求...

    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框架开发手册

    ### Nutz框架开发手册知识点详解 #### 一、引言 - **背景介绍**:随着Web开发技术的不断发展,Java虽然仍然占据着重要的地位,但其在开发效率方面相较于脚本语言存在一定的劣势。为此,Nutz框架应运而生,旨在通过...

    (源码)基于NutZ框架的权限管理系统.zip

    # 基于NutZ框架的权限管理系统 ## 项目简介 基于NutZ框架的权限管理系统是一个使用Apache Shiro进行权限管理的Web应用程序。该系统主要用于管理用户权限、角色和权限分类,并提供用户登录、登出、注册等功能。系统...

    Nutz开发用到的jar包

    Nutz是一个基于Java的轻量级框架,它提供了一系列实用工具和高质量的模块,使得Java开发者可以更加高效地进行Web应用开发。Nutz的核心特点包括轻量、快速、灵活,以及对现有Java生态系统的良好集成。这个压缩包文件...

    nutz代码生成器

    总之,Nutz代码生成器是Nutz框架下提高开发效率的有效工具,通过它,你可以快速搭建起基于Nutz的业务系统,节省时间和精力,更专注于业务功能的创新与优化。在实际开发中,结合Nutz的其他特性,如事务管理、拦截器、...

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

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

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

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

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

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

    Nutz的插件与集成库-nutzmore

    2. **Web MVC**:Nutz MVC是一个基于Nutz的Web应用开发框架,它简化了控制器编写、视图渲染以及模型数据处理。Nutzmore可能包含了一些增强MVC功能的插件,如更丰富的模板引擎支持、国际化处理等。 3. **AOP(面向切...

    nutz_redis集成依赖包

    在开发Java应用时,Nutz Redis模块是一个非常实用的工具,它使得我们能够方便地将Nutz框架与Redis键值存储系统相结合。本篇文章将详细阐述Nutz Redis集成过程中的关键知识点,以及如何避免因依赖包问题导致的困扰。 ...

    nutz需要的jar包

    Nutz是一个轻量级、高性能的Java开发框架,它提供了丰富的功能,包括MVC、ORM、DAO、AOP、IOC等,使得Java开发者能够快速地构建应用系统。本篇文章将详细探讨Nutz框架中所需的jar包以及它们在项目中的作用。 首先,...

    nutz生成javabean工具.zip

    总的来说,"nutz生成javabean工具.zip"中的Nutz Codematic是一个强大的辅助开发工具,能够帮助Java开发者快速生成符合规范的JavaBean,提高工作效率,并与Nutz框架的其他部分紧密结合,促进项目的顺利进行。...

    ztree与nutz简单使用

    zTree是一款基于JavaScript的灵活、强大的树状菜单插件,而Nutz则是一个轻量级的Java开发框架。本文将详细探讨zTree和Nutz的简单使用方法及其在实际项目中的应用。 首先,我们来看zTree。zTree的核心功能是构建动态...

    nutz框架使用手册.zip

    Nutz框架是一个基于Java语言的轻量级开源框架,它以简单、实用、高效为设计理念,为Java开发者提供了一整套全面的开发解决方案。Nutz框架由一系列子项目组成,包括Nutz IOC(依赖注入)、Nutz DAO(数据访问对象)、...

    nutz学习资料2

    标题“nutz学习资料2”表明这是一份关于Nutz框架的学习资源集合,Nutz是一个基于Java的轻量级框架,旨在提供全面的MVC支持和企业级开发工具。通过这个压缩包,我们可以期待深入理解Nutz框架的核心特性和使用方法。 ...

    nutz应用示例

    它不仅展示了如何设置和配置一个基于Nutz的Web应用,还通过具体的例子解释了Nutz与MySQL数据库的整合、数据访问、MVC架构的实现以及Ajax交互等多个关键知识点。开发者可以通过分析和运行这个项目,深入理解Nutz的...

    nutz的freemarker视图插件

    - Nutz是一个基于Java的开源框架,它提供了一套全面的工具集,包括MVC、ORM、DAO、AOP等,以提高开发效率。 - Nutz的核心理念是简洁和高效,它鼓励开发者使用原生的Java代码,而不是过度依赖框架。 - Nutz的MVC...

Global site tag (gtag.js) - Google Analytics