Giiwa轻量级分布式应用框架
Giiwa 是一个 Java Web 的快速开发框架。
模块化:模块化开发,模块之间可以复用和重载。最大化地复用代码和资源,使得构建跨项目之间的模块更加容易。
快速开发:直观简单的程序入口出口,更容易开发和维护。避免冗重设计模式,更加快速的构建模块,快速开发和部署。
轻量级分布式:并行对等分布式计算节点关系。更容易从一个节点扩展到N个节点,构建可伸缩的分布式并行计算环境。
MVC开发
简洁的MVC,更加简单程序逻辑。
后台支持Java开发,View支持Velocity, Thymeleaf, FreeMaker,HTML等。系统提供文件仓库,支持前后端代码完全分离开发。
请参考:Controller。
样例程序:https://www.giisoo.com/helo/test?name=ttttt
//org.giiwa.app.web.helo.java
//helo.java
package org.giiwa.app.web;
import org.giiwa.framework.web.Controller;
import org.giiwa.framework.web.Path;
public class helo extends Controller {
@Path(path = "test")
public void test() {
String name = this.getString("name");
this.set("name", name);
this.show("/helo.html");
}
}
//end of helo.java
// /view/helo.html
//helo.html
<!DOCTYPE html>
<html>
<body>
名字:&!name
</body>
</html>
//end of helo.html
高效数据库操作
优化的数据库访问设计,更加简单高效。
请参考: Bean, BeanDAO, Helper.W, Helper.V。
支持内嵌数据库,Postgresql,Mysql,Oracle,和MongoDB数据库,支持大数据量的高效访问,提供统一API。
//org.giiwa.demo.bean.Demo.java
//begin of the Demo Bean
package org.giiwa.demo.bean;
import org.giiwa.dao.Bean;
import org.giiwa.dao.BeanDAO;
import org.giiwa.dao.Table;
import org.giiwa.dao.Helper.V;
import org.giiwa.dao.Column;
import org.giiwa.dao.UID;
import org.giiwa.dao.X;
/**
* Demo bean
*
* @author joe
*
*/
// mapping the table name in database
@Table(name = "tbl_demo")
public class Demo extends Bean {
/**
*
*/
private static final long serialVersionUID = 1L;
// define a DAO for each Bean
public static final BeanDAO<Long , Demo> dao = BeanDAO.create(Demo.class);
// mapping the column and field
@Column(name = X.ID)
long id;
@Column(name = "name")
String name;
public long getId() {
return id;
}
public String getName() {
return name;
}
// ------------
// insert a data in database
public static long create(V v) {
/**
* generate a unique id in distribute system
*/
long id = UID.next("demo.id");
try {
while (dao.exists(id)) {
id = UID.next("demo.id");
}
dao.insert(v.force(X.ID, id));
return id;
} catch (Exception e1) {
log.error(e1.getMessage(), e1);
}
return -1;
}
}
// end of the Demo Bean
//org.giiwa.demo.web.admin.demo.java
//begin of the Controller
package org.giiwa.demo.web.admin;
import org.giiwa.dao.Beans;
import org.giiwa.dao.X;
import org.giiwa.json.JSON;
import org.giiwa.dao.Helper.V;
import org.giiwa.dao.Helper.W;
import org.giiwa.demo.bean.Demo;
import org.giiwa.web.Controller;
import org.giiwa.web.Path;
public class demo extends Controller {
@Path(login = true, access = "access.demo.admin")
public void onGet() {
// get the parameters from the request
int s = this.getInt("s");
int n = this.getInt("n", 10);
// create the query condition
W q = W.create();
String name = this.getString("name");
if (!X.isEmpty(name)) {
q.and("name", name, W.OP.like);
this.set("name", name);
}
// load data from database
Beans<Demo> bs = Demo.dao.load(q, s, n);
// set the data in the controller
this.set(bs, s, n);
// show (print) the list HTML page
this.show("/admin/demo.index.html");
}
@Path(path = "detail", login = true, access = "access.demo.admin")
public void detail() {
// get the parameter from the request
long id = this.getLong("id");
// load data from the database
Demo d = Demo.dao.load(id);
// set the data in controller
this.set("b", d);
this.set("id", id);
// show (print) the detail HTML page
this.show("/admin/demo.detail.html");
}
@Path(path = "delete", login = true, access = "access.demo.admin")
public void delete() {
// get the parameter from the request
long id = this.getLong("id");
// delete the data from the database
Demo.dao.delete(id);
// response (print) the json to response
this.response(JSON.create().append(X.STATE, 200).append(X.MESSAGE, lang.get("delete.success")));
}
@Path(path = "create", login = true, access = "access.demo.admin")
public void create() {
// is POST method?
if (method.isPost()) {
// create the value object
V v = V.create();
v.set("name", this.getString("name"));
// insert the data into database
Demo.create(v);
// response(print) the json to response
this.response(JSON.create().append(X.STATE, 200).append(X.MESSAGE, lang.get("save.success")));
return;
}
// show (print) the create HTML page
this.show("/admin/demo.create.html");
}
// web api: /admin/demo/edit?id=
@Path(path = "edit", login = true, access = "access.demo.admin")
public void edit() {
// get the parameter from the request
long id = this.getLong("id");
// is POST method?
if (method.isPost()) {
// create the value object
V v = V.create();
v.set("name", this.getString("name"));
// update the data in database
Demo.dao.update(id, v);
// response (print) the json to response
this.response(JSON.create().append(X.STATE, 200).append(X.MESSAGE, lang.get("save.success")));
return;
}
// load the data from the database
Demo d = Demo.dao.load(id);
// set the data in Controller
this.set(d.getJSON());
this.set("id", id);
// show (print) the edit HTML page
this.show("/admin/demo.edit.html");
}
}
// end of the Controller
模块管理
模块化开发,轻松创建模块工程文件,生成模块样例文件。
包含完整的模块生命周期管理,应用模块可以添加自己的处理逻辑在模块生命周期各个阶段。
//module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module version="1.0">
<id>652</id>
<name>demo</name>
<package>org.giiwa.demo.web</package>
<version>1.0</version>
<build>0</build>
<enabled>true</enabled>
<readme>demo</readme>
<listener>
<!--add module listener here, please refer IListener interface-->
<class>org.giiwa.demo.web.DemoListener</class>
</listener>
<filter>
<!--TODO, please refer web.IFilter, eg. <pattern>/user/login</pattern>,<class>org.giiwa.demo.web.UserFiler</class>-->
</filter>
<required>
<!--add all required modules here-->
<module name="default" minversion="1.6.1901131542"
maxversion="1.6.*" />
</required>
<key>MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKWDm99lG8Oy5b93ptb+v0lrI2O4PK4oujb4pHfq9FUJiFECe/lotkgEpjwT+4Q2LmUJpTBRSpEAGrAJfxidGgOs6kxUtEBSEfPvkifUDCmKzsvOd3R4dbfBiF0qDSxiwBV9PWwXg1TBYio345yJIRosO1JETnLdgPk/6zokMDvLAgMBAAECgYEAm6rKQTNRB6AMISYhzndN5XlUkYdH2u0HJoh39ykNn6UVhkt12j83oUhuKHcKyXBD9lc5+9WY8gNNFl/4H2gye9tEJQ5CAVoUdky79kVtkB55Aa+io0cGNA/xmhsRnpZB/ZRazBZ4dIeRoEfLWM0Ki/zr6H2VFFi737jIUlf/8DECQQDN/ZvJ/aNe6AugNaLIryZpBzIrBa2xxyK/REnpFVJGeNq84hb6n8TqZVCkk9nTTBazCptcWjuod8mJwMITANJNAkEAzbJeLjtg5r8EWza6na8kIB871ouKJdxYwr88hrx0A9aClcrYpFvA8rbgQ76Z1QJjV3dQfP38Bg+0g6MK3AFidwJAS7CBWwIw0oGvK+opa1Y4ZeU4AOjwPt+uG9uq0NN9zNlBfqAQ03x7balWrXKKWoKd4KHoHlIlk6yYSF6ksTjfDQJABV+TdkG21lBHHNrhJR1eJDisp34drb+D0hKM0jg6D5+a6a7S2fhLoguE8EAaZKYbUj2brKg13TKr1IR91CF1IQJASVILcBNP83XF/WHny5YacSalyxTdTihIISV6Jw42KFEcgIQ85iqKhZFOhibZYq9w45/XXZPgr4vP64ScUXq3iA==</key>
</module>
//end of the module.xml
//org.giiwa.demo.web.DemoListener.java
//begin of the DemoListener
package org.giiwa.demo.web;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.giiwa.demo.task.TestTask;
import org.giiwa.bean.License;
import org.giiwa.web.IListener;
import org.giiwa.web.Module;
public class DemoListener implements IListener {
static Log log = LogFactory.getLog(DemoListener.class);
@Override
public void onStart(Configuration conf, Module m) {
log.info("webdemo is starting ...");
// set the license of this module
m.setLicense(License.LICENSE.free,
"f3VOF0UAnJPBRlucnMpWXrn/7q9cbeY2VVXsphwE/iLJGPB1+1hUUHLdZOLWEafPm6hbOkvXAK9xGZuNCyTBczpib+NNizqqhLis4eODBQYHLePmEYJDdMwnDi+Z8TMNOL/uCm6rverY06qWzedJ6IWdq5ev8LJ5mUkI8gHrhcg=");
// start a test task here
TestTask.start();
}
@Override
public void onStop() {
log.info("webdemo is stopping ...");
// stop the test tasj
TestTask.stop();
}
@Override
public void uninstall(Configuration conf, Module m) {
//uninstall the module
}
@Override
public void upgrade(Configuration conf, Module m) {
//upgrade the module
}
}
// end of the DemoListener
分布式并行计算
轻量级分布式计算平台,从1个节点到n个节点任意扩展,节点之间都为对等关系,没有主从区别。
分布式计算环境包括:高速缓存,消息系统,分布式锁,分布式文件系统,分布式计算任务。
请参考: Task, MQ, Cache, Global.getLock。
//org.giiwa.demo.task.TestTask.java
//begin of the TestTask
package org.giiwa.demo.task;
import java.util.Arrays;
import org.giiwa.bean.X;
import org.giiwa.task.Task;
public class TestTask extends Task {
/**
*
*/
private static final long serialVersionUID = 1L;
public static TestTask inst = new TestTask();
private boolean stop = false;
@Override
public String getName() {
// the task name, MUST global unique in JVM
return "test.tsk";
}
@Override
public void onFinish() {
// re-run this task at a minute alter
if (!stop) {
this.schedule(X.AMINUTE);
}
}
@Override
public void onExecute() {
// do something
try {
// mapreduce, create sub task for the stream and dispatch the task to each node
// and each core
Task.mapreduce(Arrays.asList(1, 2, 3, 4), e -> {
return e * 100;
}, e -> {
System.out.println(e);
});
} catch (Exception e1) {
e1.printStackTrace();
}
}
public static void start() {
inst.stop = false;
inst.schedule(0);
}
public static void stop() {
inst.stop = true;
inst.stop(true);
}
}
//end of the TestTask
评论