从应用示例来认识Tiny框架

简介:

呵呵,Tiny框架神龙见首不见尾已经许多时间了,里面只看到一些几个孤零零的子框架。今天就通过Tiny开发示例的方式来重点展示一下利用Tiny框架是如何开发的。

HelloWorld

首先从这个神一样的示例写起。

服务开发:

方式1:注解方式

?
1
2
3
4
5
6
7
8
9
10
11
12
@ServiceComponent ()
public class HelloWorldAnnotationService{
     @ServiceMethod (serviceId = "sayHelloA" )
     @ServiceResult (name = "result" )
     @ServiceViewMapping ( "/helloworld/helloresult.page" )
     public String sayHello(String name) {
         if (name == null ) {
             name = "world." ;
         }
         return "hello," + name;
     }
}

解释:

@ServiceMethod(serviceId = "sayHelloA")声明服务ID,必须不能重复,保证唯一

@ServiceResult(name = "result")声明返回结果在服务调用完之后旋转在数据总线的名称

@ServiceViewMapping("/helloworld/helloresult.page")声明如果调用服务之后转向的展现页面,可省略

表单输入界面:helloworld.page

?
1
2
3
4
5
服务方式:
< form action = "sayHelloA.servicepage" >
  输入名称:< input type = "text" name = "name" />
  < input type = "submit" value = "提交" />
</ form >

运行结果界面:

helloresult.page

?
1
$!result

方式2:Xml配置方式

?
1
2
3
4
5
6
7
8
public class HelloWorldXmlService{
     public String sayHello(String name) {
         if (name == null ) {
             name = "world." ;
         }
         return "hello," + name;
     }
}

上面写完类之后,还要再加一个配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< service-components >
     < service-component type = "org.tinygroup.helloworld.service.HelloWorldXmlService"
         group-id = "org.tinygroup" artifact-id = "helloworldservice" >
         < service-method name = "sayHello" local-name = "sayHello"
             service-id = "sayHello" version = "" description = ""
             method-name = "sayHello" >
             < service-parameters >
                 < service-parameter name = "name" type = "java.lang.String"
                     required = "true" is-array = "false" />
             </ service-parameters >
             < service-result name = "result" required = "false"
                 is-array = "false" type = "java.lang.String" />
         </ service-method >
     </ service-component >
</ service-components >

这段Xml手工写还是有点麻烦的,不过没关系,咱有工具:

如果想在调用服务之后自动转向到一个页面,则要再配下面的xml

?
1
2
3
< service-view-mappings >
     < service-view-mapping service-id = "sayHello" path = "/helloworld/helloresult.page" type = "forward" ></ service-view-mapping >
</ service-view-mappings >

表单输入界面:helloworld.page

?
1
2
3
4
5
服务方式:
< form action = "sayHello.servicepage" >
  输入名称:< input type = "text" name = "name" />
  < input type = "submit" value = "提交" />
</ form >

运行结果界面:

helloresult.page

?
1
$!result

方式3:流程编排方式

要通过流程编排方式实现,先要写一个组件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class HelloWorldComponent implements ComponentInterface {
     String name;
     String resultKey;
     public String getResultKey() {
         return resultKey;
     }
     public void setResultKey(String resultKey) {
         this .resultKey = resultKey;
     }
     public String getName() {
         return name;
     }
     public void setName(String name) {
         this .name = name;
     }
     public void execute(Context context) {
         context.put(resultKey, String.format( "Hello, %s" , name));
     }
}
写完组件之后,还要编写组件定义文件来定义组件的定义文件,当然要做成组件,就一定要有通用性,这样就可以一次定义,到处使用,对于只用一次的,这么做就不方便了。
?
1
2
3
4
5
6
7
8
9
10
< components >
     < component name = "helloworld" bean = "helloworld"
         title = "HelloWorld组件" category = "测试组件" icon = "/icon/component.gif" >
         < short-description >helloworld component</ short-description >
         < long-description >helloworld component long description
         </ long-description >
         < parameter name = "name" title = "名字" type = "java.lang.String" ></ parameter >
         < parameter name = "resultKey" title = "结果键值" type = "java.lang.String" ></ parameter >
     </ component >
</ components >

OK,现在流程组件就开发完毕了。

就可以像上面一样在可视的流程编辑器中进行可视化开发了。

表单输入页面:

/helloworld.page

?
1
2
3
4
5
流程方式:
< form action = "helloworld.pageflow" >
  输入名称:< input type = "text" name = "name" />
  < input type = "submit" value = "提交" />
</ form >
运行结果页面:

helloresult.page

?
1
$!result

上面的展现简单是简单了点,但是容易理解。

通过上面的HelloWorld,我们对Tiny框架的服务开发及界面开发及控制层的开发都有了一定的了解,下面我们就进入更加复杂一点的示例:

四则运算

由于前面一节已经有了一定了解,因此这一节就只贴代码,解释就省了。

通过注解方式开发服务

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@ServiceComponent()
public class FourOperateAnnotationService{
     @ServiceMethod(serviceId = "additionWithAnno" )
     @ServiceResult(name = "result" )
     @ServiceViewMapping( "/fouroperate/result.page" )
     public double addition( double number1, double number2){
         return number1+number2;
     }
     @ServiceMethod(serviceId = "subtractWithAnno" )
     @ServiceResult(name = "result" )
     @ServiceViewMapping( "/fouroperate/result.page" )
     public double subtraction( double number1, double number2){
         return number1-number2;
     }
     @ServiceMethod(serviceId = "multiWithAnno" )
     @ServiceResult(name = "result" )
     @ServiceViewMapping( "/fouroperate/result.page" )
     public double multi( double number1, double number2){
         return number1*number2;
     }
     @ServiceMethod(serviceId = "divisionWithAnno" )
     @ServiceResult(name = "result" )
     @ServiceViewMapping( "/fouroperate/result.page" )
     public double division ( double number1, double number2){
         return number1/number2;
     }
}

通过Xml配置方式开发服务

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class FourOperateXmlService{
     
     public Double addition(Double number1,Double number2){
         return number1+number2;
     }
     
     public Double subtraction(Double number1,Double number2){
         return number1-number2;
     }
     
     public Double multi(Double number1,Double number2){
         return number1*number2;
     }
     
     public Double division (Double number1,Double number2){
         return number1/number2;
     }
}

通过流程方式开发服务

下面先搞个抽象类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public  abstract class AbstractFourOperateComponent implements ComponentInterface {
     protected double number1;
     protected double number2;
     protected String resultKey;
     public String getResultKey() {
         return resultKey;
     }
     public void setResultKey(String resultKey) {
         this .resultKey = resultKey;
     }
     public double getNumber1() {
         return number1;
     }
     public void setNumber1( double number1) {
         this .number1 = number1;
     }
     public double getNumber2() {
         return number2;
     }
     public void setNumber2( double number2) {
         this .number2 = number2;
     }
}
接下来就简单了:
?
1
2
3
4
5
6
7
public class AdditionComponent extends AbstractFourOperateComponent {
 
     public void execute(Context context) {
         context.put(resultKey, number1+number2);
     }
 
}
?
1
2
3
4
5
6
7
public class DivisionComponent extends AbstractFourOperateComponent {
 
     public void execute(Context context) {
         context.put(resultKey, number1/number2);
     }
 
}
?
1
2
3
4
5
6
7
public class MultiComponent extends AbstractFourOperateComponent {
 
     public void execute(Context context) {
         context.put(resultKey, number1*number2);
     }
 
}
?
1
2
3
4
5
6
7
public class SubtractionComponent extends AbstractFourOperateComponent {
 
     public void execute(Context context) {
         context.put(resultKey, number1-number2);
     }
 
}

然后就可以通过编辑器,可视化编辑了。

由于这里主要说明服务端的开发,因此客户端的开发就省略了,其实也是非常简单的。

数据库示例

搞开发,怎么能不搞数据库呢??

下面展现一下数据的开发:

采用Hibernate来开发数据库应用

首先搞个Pojo

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class User {
 
     private int id; 
     private String name;
     private int age;
     public int getId() {
         return id;
     }
     public void setId( int 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;
     }
}
接下来配个hbm文件:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
<? xml version = "1.0" ?> 
<! DOCTYPE hibernate-mapping PUBLIC  
     "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
< hibernate-mapping package = "org.tinygroup.crud.pojo"
     < class name = "User" table = "user"
         < id name = "id"
             < generator class = "native" /> 
         </ id
         < property name = "name" /> 
         < property name = "age" /> 
     </ class
</ hibernate-mapping >
再接下来写个Dao:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class HibernateCrudDao extends HibernateDaoSupport implements CrudDbDao<User>{
 
     public void addUser(User user) {
           getHibernateTemplate().save(user);       
     }
 
     public void updateUser(User user) {
         getHibernateTemplate().update(user);
     }
 
     public void deleteUser(User user) {
         getHibernateTemplate().delete(user);
     }
 
     @SuppressWarnings ( "unchecked" )
     public List<User> queryUsers(User user) {
         if (user== null ){
             return getHibernateTemplate().loadAll(User. class );
         }
         return getHibernateTemplate().findByExample(user);
     }
 
     public User queryUserById( int id) {
         return (User) getHibernateTemplate().get(User. class , id);
     }
 
}
接下来实现服务:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@ServiceComponent ()
public class HibernateCrudService implements CrudDbService<User> {
     
     private CrudDbDao<User> crudDbDao;
     
     public CrudDbDao<User> getCrudDbDao() {
         return crudDbDao;
     }
 
     public void setCrudDbDao(CrudDbDao<User> crudDbDao) {
         this .crudDbDao = crudDbDao;
     }
     @ServiceMethod (serviceId = "addUser" )
     @ServiceViewMapping (value= "/queryUsers.servicepage" ,type= "redirect" )
     public void addUser(User user) {
          crudDbDao.addUser(user);
     }
     @ServiceMethod (serviceId = "updateUser" )
     @ServiceViewMapping (value= "/queryUsers.servicepage" ,type= "redirect" )
     public void updateUser(User user) {
          crudDbDao.updateUser(user);
     }
     @ServiceMethod (serviceId = "deleteUser" )
     @ServiceViewMapping (value= "/queryUsers.servicepage" ,type= "redirect" )
     public void deleteUserById( int id) {
         User user=getUserById(id);
         crudDbDao.deleteUser(user);
     }
     @ServiceMethod (serviceId = "queryUsers" )
     @ServiceResult (name = "users" )
     @ServiceViewMapping ( "/crud/service/hibernate/list.page" )
     public List<User> queryUsers(User user) {
         return crudDbDao.queryUsers(user);
     }
     @ServiceMethod (serviceId = "queryUserById" )
     @ServiceResult (name = "user" )
     @ServiceViewMapping ( "/crud/service/hibernate/operate.page" )
     public User getUserById(Integer id) {
         if (id== null ){
             return null ;
         }
         return crudDbDao.queryUserById(id);
     }
 
}
没错,你看起来这里的服务都是直接调用dao里的方法的,对于这个简单例子看起来有点重复,但是实际应用中是不可能直接把dao发布成服务的,因此你可以想像一下这里有好多步操作就好了。

至此基于Hibernate就可以开发完毕了。

采用TinyDB来实现

TinyDB采用了No Pojo,No Dao的解决方案:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@ServiceComponent ()
public class TinyDbCrudService extends BeanSupport implements CrudDbService<Bean>{
     
     private DBOperator operator;
     
     private BeanOperatorManager manager;
     
     private String beanType;
     
     public void setBeanType(String beanType) {
         this .beanType = beanType;
     }
 
     public void setManager(BeanOperatorManager manager) {
         this .manager = manager;
     }
 
      /** 初始化bean。 */
     protected void init() throws Exception {
         Assert.assertNotNull(manager, "manager must not null" );
         operator=manager.getDbOperator(beanType);
     }
     
     
     @ServiceMethod (serviceId = "addUserTiny" )
     @ServiceViewMapping (value= "/queryUsersTiny.servicepage?@beantype=user" ,type= "redirect" )
     public void addUser(Bean user) {
         operator.insert(user);
     }
     @ServiceMethod (serviceId = "updateUserTiny" )
     @ServiceViewMapping (value= "/queryUsersTiny.servicepage?@beantype=user" ,type= "redirect" )
     public void updateUser(Bean user) {
         operator.update(user);
     }
     @ServiceMethod (serviceId = "deleteUserTiny" )
     @ServiceViewMapping (value= "/queryUsersTiny.servicepage?@beantype=user" ,type= "redirect" )
     public void deleteUserById( int id) {
         operator.deleteById(id);
     }
     @ServiceMethod (serviceId = "queryUsersTiny" )
     @ServiceResult (name = "users" )
     @ServiceViewMapping ( "/crud/service/tinydb/list.page" )
     public List<Bean> queryUsers(Bean user) {
         if (user== null ){
             user= new Bean(beanType);
         }
         Bean[] beans= operator.getBeans(user);
         return Arrays.asList(beans);
     }
     @ServiceMethod (serviceId = "queryUserByIdTiny" )
     @ServiceResult (name = "user" )
     @ServiceViewMapping ( "/crud/service/tinydb/operate.page" )
     public Bean getUserById(Integer id) {
         if (id== null ){
             return null ;
         }
         return operator.getBean(id);
     }
 
}
OK,这样就算完成了。

够简单么??NO,还不够简单。

实际上TinyDB中对于常用的CRUD,根本就不用写代码,框架默认就全部支持了,所以只有复杂的业务逻辑的都需要像上面一样写一下,简单的CRUD,就不用写了。

通过流程方式开发

框架内嵌已经包含了常用的数据库处理组件:

哇,只要拖拖配配就可以了。

页面流

页面流是Tiny框架推荐的控制层解决方案,它强大,简单,可视性好。

呵呵,是不是实现简单,看起来清晰?

当然它的强大在这么简单的例子里是看不到的。

WEB工程

从上面的示例来看,它的界面确实是简单的。然后上面的三个工程最后打了3个Jar包,就算开发完毕了。

在我们的Web工程中,我们要添加这些示例,只要修改pom文件即可:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< dependency >
             < groupId >org.tinygroup</ groupId >
             < artifactId >org.tinygroup.helloworld</ artifactId >
             < version >1.2.0-SNAPSHOT</ version >
         </ dependency >
         < dependency >
             < groupId >org.tinygroup</ groupId >
             < artifactId >org.tinygroup.fouroperate</ artifactId >
             < version >1.2.0-SNAPSHOT</ version >
         </ dependency >
         < dependency >
             < groupId >org.tinygroup</ groupId >
             < artifactId >org.tinygroup.crud</ artifactId >
             < version >1.2.0-SNAPSHOT</ version >
         </ dependency >
POM添加了,功能就添加了;POM删除了,功能就删除了,这就是Tiny框架中所说的模块化。

UI引擎

示例完成之后,我对做示例的同学说,你这个示例写得还是可以的,但是我展示的时候很不方便,我要记得每个地址,这对我要求也太高了,能不能给我搞个菜单出来??

此同学说好的,结果他创建了一个default.layout文件,加了如下的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< table border = "1" width = "100%" >
    < tr >
       < td colspan = "2" >
     helloworld示例:< a href = "${TINY_CONTEXT_PATH}/helloworld/helloworld.page" >helloworld</ a >< br />
           四则运算示例:< a href = "${TINY_CONTEXT_PATH}/fouroperate/fouroperate.page" >四则运算</ a >< br />
           增删改查示例:< a href = "${TINY_CONTEXT_PATH}/crud/crud.page" >增删改查</ a >< br />
       </ td >
     </ tr >
     < tr
       < td width = "20%" >内容展示</ td >
       < td >
          $pageContent
       </ td >
    </ tr >
</ table >
然后我就在访问所有页面的时候都有菜单可用了,这就是TinyUI框架中的装饰。

应用截图

首页:

点击helloworld进入helloworld示例首页

再点下面的服务方式后的helloworld链接

输入abc之后,点提交:

结果就出来了。

下面是数据访问页面:

添加界面:

四则运算界面:

呵呵,不要嫌界面丑,界面丑是因为我不想引入复杂的页面使得注意力转移到其它地方。

总结

上面用了三个例子:HelloWorld,四则运算,数据库访问来对Tiny框架的开发过程进行了展示。当然,Tiny框架提供的实际内容要远远多于你上面看到的内容,比如:

  1. 对页面的局部刷新有强有力的支持,便于进行Ajax处理
  2. 提供Bigpipe模式来提升用户体验
  3. 提供CSS合并、提供JS合并,提供内容压缩输出到浏览器端
  4. 上面开发的所有服务都可以提供xml,json方式结果的返回,也可以通过webservice进行访问
  5. 提供分层部署能力
  6. 提供集群部署支持,接入服务器可以水平进行扩展,应用服务器可以进行水平扩展。
相关文章
|
6月前
|
人工智能 数据挖掘 API
AutoGen完整教程和加载本地LLM示例
Autogen是一个卓越的人工智能系统,它可以创建多个人工智能代理,这些代理能够协作完成任务,包括自动生成代码,并有效地执行任务。
388 0
|
7月前
|
API UED
SAP UI5 里 /IWBEP/VOC_COMMON 的含义和作用是什么
SAP UI5 里 /IWBEP/VOC_COMMON 的含义和作用是什么
44 0
|
XML 机器人 Java
Robot Framework(5)- 使用测试库
Robot Framework(5)- 使用测试库
233 0
Robot Framework(5)- 使用测试库
|
Android开发
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(三)
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(三)
105 0
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(三)
|
存储 缓存 编解码
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(一)
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(一)
135 0
|
存储 缓存 Java
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(二)
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(二)
209 0
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )(二)
Py之MT:Multithreaded的简介、引入、使用方法之详细攻略(一)
Py之MT:Multithreaded的简介、引入、使用方法之详细攻略
Py之MT:Multithreaded的简介、引入、使用方法之详细攻略(一)
|
程序员 Python
Py之MT:Multithreaded的简介、引入、使用方法之详细攻略(一)
Py之MT:Multithreaded的简介、引入、使用方法之详细攻略
Py之MT:Multithreaded的简介、引入、使用方法之详细攻略(一)
|
Java TensorFlow API
TensorFlow Lite源码解析--模型加载和执行
TensorFlow Lite是专门针对移动和嵌入式设备的特性重新实现的TensorFlow版本。相比普通的TensorFlow,它的功能更加精简,不支持模型的训练,不支持分布式运行,也没有太多跨平台逻辑,支持的op也比较有限。但正因其精简性,因此比较适合用来探究一个机器学习框架的实现原理。不过准确讲,从TensorFlow Lite只能看到预测(inference)部分,无法看到训练(t
7278 0
|
iOS开发
Core Audio 框架详细解析
Core Audio框架详细解析(一) —— 基本概要Core Audio框架详细解析(二) —— 基于CoreAudio的ios音频服务总结分析
1279 0