`
lthu
  • 浏览: 58834 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Rose4J 新的WEB开发引擎

    博客分类:
  • java
阅读更多

最新内容请参考www.rose4j.cn

根据我的经验,一个典型的Web应用中的代码比例如下:
页面逻辑约占 50%,商业逻辑约占30%, O/R 约占20%。

但事实上,页面却是最不受重视的部分,从来都被认为是脏活,累活,杂活。典型的开发过程通常是这样:
页面设计人员迅速的用Dreamweaver等生成一堆文本杂乱无章的页面,然后交给JSP程序员加入更加杂乱无章的Java代码和Taglib。
当页面布局风格需要改变的时候,页面设计人员用Dreamweaver等生成一堆新的页面。JSP程序员再重新加入更加杂乱无章的Java代码Taglib。
至于页面中的脚本逻辑调试,更是一门精深的工夫了。

根据社会规则,通常来说,工作内容越轻松,收入越高;工作内容越脏月累,收入越低;Web开发也是如此:做着最脏最累的活的页面程序员,工资一般比不上后台业务逻辑程序员。

开发框架通常会带来这样的结果:让简单的东西,变得更简单;让复杂的东西,变得更复杂。

于是就有了研发RoseForJ的想法,希望有前台页面与后台java程序能完全分开,当程序员拿到页面嵌入java代码后,在Dreamweaver中不会影响页面排版效果,当页面需要修改时,页面设计人员用Dreamweaver进行修改时不影响现有的页面。

wicket、xmlc 、Tapestry 等已有此项功能,wicket在服务器端的编程过于复杂,Freemarker, Velocity在view层和html混合在一起,嵌入代码后的页面在Dreamweaver中一般会乱掉。

RoseForJ的思路是 Velocity在XML DOM领域的扩展。

如果说,Fastm = JDynamiTe + Wicket;DOMPlus = XMLC + Wicket,那么RoseForJ=xmlc+wicket+velocity

下面我们来看看RoseForJ的模板

 

  1. >  
  2. <html xmlns:j="http://www.mobi99.cn">  
  3. <head>  
  4. <title>${title}title>  
  5.   
  6. head>  
  7.   
  8. <body>  
  9. <ul>  
  10.  <li j:foreach="${dataSet}" j:item="${data}">  
  11.   <span j:tid='${data.getName()}' id="showname">这里显示NAMEspan>  
  12.         <j:tempnode j:tid='${data.getName()}'>这里显示NAMEj:tempnode>  
  13.    <img src="http://localhost/roseforj/listImg.do?id=${data.getId()}" width="200" />  
  14.    xxx.id=${xxx.getId()}   
  15.  li>  
  16. ul>  
  17. <j:include path='/xml/include.html'/>  
  18. body>  
  19. html>  

 


从上面模板可以看出RoseForJ只有两个TAG(tempnode、include)和3个属性(foreach、item,tid),它也是一个标记语言,写法如下 ${变量表达式} 。

          其中3个属性可用于html任何标签(如用于tr ,td等),foreach、item配合使用,表示一个循环,foreach="${dataSet}"   ,此时dataSet是一个集合对象或数组,item="${data}" ,data表示集合对象或数组对象中每一个成员。

         ${变量表达式} 的用法非常灵活,可在任何位置,如上面的用法:

1、这里作为TAG 的text的值,运行结束后将替换掉 "这里显示NAME" 这段文本

  1. <span j:tid='${data.getName()}' id="showname">这里显示NAMEspan>  

2、此处用法是作为HTML TAG img的属性src的参数值。

  1. <img src="http://localhost/roseforj/listImg.do?id=${data.getId()}" width="200" />  


3、xxx.id=${data.getId()} 可以直接输出。

         两个TAG(tempnode、include)中include不用说一看就知道是引入外面的一个模板文件,tempnode的作用是在解析完成后,会将此tempnode节点删除,如在此处的应用

xml 代码
  1. <div class="dtree">      
  2. <a href="javascript: d.openAll();">展开a> | <a href="javascript: d.closeAll();">关闭>      
  3. <script type="text/javascript">      
  4.  d = new dTree('d');       
  5.         
  6.  d.add(0,-1,'系统菜单','#',"showMenu",null);        
  7.  <j:tempnode j:foreach="${MenuSet}" j:item="${data}">      
  8.   d.add('${data.get("id")}','${data.get("i_parentid")}','${data.get("c_title")}','${data.get("c_target")}');       
  9. j:tempnode>        
  10.  document.write(d);       
  11. script>
  12.   


我们都知道在script TAG中是不允许出现其它tag的,所以此处的运行结果为:

xml 代码
  1. <script type="text/javascript">  
  2.     d = new dTree('d');   
  3.        
  4.     d.add(0,-1,'系统菜单','#',"showMenu",null);    
  5.        
  6.         d.add('1','0','频道管理','../channel/listChannel.do','mainFrame');   
  7.        
  8.         d.add('2','0','内容管理','../content/listContent.do','mainFrame');   
  9.        
  10.         d.add('3','1','新增频道','../channel/editChannel.do','mainFrame');   
  11.        
  12.         d.add('4','2','新增内容','../content/editContent.do','mainFrame');   
  13.        
  14.         d.add('5','0','角色管理','../role/listRole.do','mainFrame');   
  15.        
  16.         d.add('6','0','用户管理','../user/listUser.do','mainFrame');   
  17.        
  18.         d.add('7','5','新增角色','../role/editRole.do','mainFrame');   
  19.        
  20.         d.add('8','6','新增用户','../user/editUser.do','mainFrame');   
  21.        
  22.         d.add('9','0','菜单管理','../menu/listMenu.do','mainFrame');   
  23.        
  24.         d.add('10','9','新增菜单','../menu/editMenu.do','mainFrame');   
  25.        
  26.     document.write(d);   
  27. script>  


从上面的代码可以看出tempnode 节点被删除了

在服务器端的编程则更加简单,几乎没有任何约束,你可以用hibernate,ibaits,javabean或者自己组织的任何对象,同时还可以嵌套使用,如:

java 代码
  1. package juan.framework;   
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;   
  5.   
  6. public class ValueObject {   
  7.    private int id=0;   
  8.    private String name="tom";   
  9.       
  10.    private List aList=new ArrayList();   
  11.       
  12.    public List getList() {   
  13.       return aList;   
  14.    }   
  15.   
  16.    public void setList(List list) {   
  17.       aList = list;   
  18.    }   
  19.   
  20.    public int getId() {   
  21.       return id;   
  22.    }   
  23.   
  24.    public void setId(int id) {   
  25.       this.id = id;   
  26.    }   
  27.   
  28.    public String getName() {   
  29.       return name;   
  30.    }   
  31.   
  32.    public void setName(String name) {   
  33.       this.name = name;   
  34.    }   
  35. }   
  36.   
  37.   
  38. package juan.framework;   
  39.   
  40. import java.util.ArrayList;   
  41. import java.util.List;   
  42. import java.util.Vector;   
  43.   
  44. import juan.framework.context.IContext;   
  45. import juan.framework.context.impl.InnerContextImpl;   
  46. import juan.framework.runtime.RuntimeSingleton;   
  47.   
  48. public class Test {   
  49.   
  50.    /**  
  51.     * @param args  
  52.     */  
  53.    public static void main(String[] args) throws Exception{   
  54.       String filename = "/xml/hell.html"//要访问的模板path   
  55.       Vector paths = new Vector();   
  56.       paths.add("E:\\workspace\\Test\\juan");  //模板存放的path,可以有多个   
  57.       RuntimeSingleton.init(paths);   
  58.   
  59.   
  60.       IContext context=new InnerContextImpl();   
  61.       context.put("title""www.mobi99.cn");   
  62.          
  63.       ValueObject vo1=new ValueObject();   
  64.       vo1.setId(9999);   
  65.       vo1.setName("vovovovovov");   
  66.          
  67.       context.put("data", vo1);    
  68.          
  69.          
  70.       List aList=new ArrayList();    
  71.       ValueObject[] xxSet=new ValueObject[2];   
  72.          
  73.       ValueObject vo=new ValueObject();   
  74.       vo.setId(100);   
  75.       vo.setName("tony");   
  76.          
  77.          
  78.       aList.add(vo);   
  79.       xxSet[0]=vo;   
  80.          
  81.       vo=new ValueObject();   
  82.       vo.setId(200);   
  83.       vo.setName("tom");   
  84.       aList.add(vo);   
  85.       xxSet[1]=vo;   
  86.          
  87.       context.put("dataSet", aList);   
  88.       context.put("xxSet", xxSet);   
  89.   
  90.       RuntimeSingleton.getTemplate(filename, "GBK").merge(context,null); //此处null为writer,demo中省掉了   
  91.    }   
  92. }   
  93.   

从上面的编码中可以看出RoseForJ对数据的要求几乎是没有任何要求的,可以是pojo 如可以这样用${data.getName()},也可以是个集合类,则可以这样取值${data.get("c_author")} ,还可以嵌套调用如:${ChannelFactory.get(data.get("c_channelid"))} ,data.get("c_channelid")运行的结果作为ChannelFactory.get(...)的参数,另外RoseForJ还提供了格式化输出等工具,如日期输出${DateTool.format("yyyy-MM-dd",data.get("t_starttime"))} ,数学运算

a href="listContent.do?pages=${MathTool.sub(iPageCurrent,1)}">上一页
a href="listContent.do?pages=${MathTool.add(iPageCurrent,1)}">下一页

 太晚了,明天再接着写

 

 

 

分享到:
评论
8 楼 lthu 2007-11-12  
remove用法说明:
    假设我们要完成这样一个功能,当变量(int) a>1时我们需要显示<input name="old.id" value="this is old value"/>,当 a<=1时我们需要显示<input name="id" value="this is new value"/>,那么我们就可以这样实现:

1、在java端编写一个功能类

public class XXUtil{
   public static boolean isOld(int a){
      if(a>1)return true;
     
      return false;
   }

   public static boolean isNew(int a){
      if(a<=1)return true;
     
      return false;
   }
}

并将这个类放入context中


然后view层就可以这样描述:
<input name="old.id" value="this is old value" j:remove="${XXUtil.isOld(a)}"/>
<input name="id" value="this is new value" j:remove="${XXUtil.isNew(a)}"/>

这相当于jstl里的
<c:if test="a>1">
    <input name="old.id" value="this is old value" j:remove="${XXUtil.isOld(a)}"/>
<c:else>
    <input name="id" value="this is new value" j:remove="${XXUtil.isNew(a)}"/>
</c:if>

在运行时其中一个input肯定会被删除掉,这样就完成了if的功能,在这里我只是举例说明,你也可以将这两个(或多个)input合并成一个,需要变化的部分全用变量代替(如下)。这样一来所有的逻辑(包括界面逻辑)全在服务器端实现,界面仍然非常简洁。

<input name="${xxx.name}" value="${xxx.value}" j:remove="${XXUtil.isOld(a)}"/>
此时这一行就代表了多个if else,当然XXUtil这个类的逻辑也要做相应的修改了。
7 楼 lthu 2007-11-12  
RoseForJ只有两个TAG(tempnode、include)和4个属性(foreach、item,tid,remove)
6 楼 lthu 2007-11-12  
当初在设计view层时,并不想在view层放入太多的逻辑,但对于常规的应用还是有考虑的,roseforj有个remove属性 当它为true时就会保留到页面,为false时则会动态地删除,也就是说在运行时会删除这个节点,而remove可以写死(如:remove=true等),也可以由后台控制(remove=${java表达式}),由此功能实现if操作,这样一来在view层的代码也是最少的,页面也是最干净的
5 楼 差沙 2007-11-09  
怎么做if的操作呢?
4 楼 lthu 2007-09-11  
hi fyting:

很高兴你能看我写的东西,最近公司比较忙,所以roseforj网站一直没更新,roseforj 1.0.8版本以前view层用的一直是velocity,但麻烦的是我的网站是DIV+CSS风格的,所以在Dreamweaver里只要嵌入velocity代码,页面就乱成一团,没办法调整,所以就自己写了这个东西,它不会影响在Dreamweaver中的排版,过几天我会把这个框架的源码开放出来,希望对大家有些帮助。
3 楼 fyting 2007-09-11  
这个模板语言的语法看起来不错,把语句嵌入了普通的html tag,倒似乎有一点点类似Tapstry呵呵。但是我看你的网站上发布的文档,怎么又是一个Web框架呢,而且使用了velocity作的模板?
2 楼 lthu 2007-09-10  
hi wl95421 :

很高兴你能看我写的东西,在这里我就你的问题说说我的想法

你的第一个问题谈到了权限控制,我第一个想到roseforj模板引擎应该不会处理权限问题,于是我我想你的权限控制可能指的是功能级的(你要实现的可能是具体到某个按钮),roseforj只是个模板引擎,跟逻辑没什么关系,所以不会处理这些东西,实际上这是你的方案问题,我建议你用js进行处理,当权限不够时,可以通过JS将按钮从页面中删除,这样或许能满足你的目地。

你的第二个问题是如何复用,这个问题我还是觉得奇怪,我觉得这也是你的设计问题,在服务器端,roseforj没有任何要求和约束,所以如何复用应该是设计人员要想的问题,wicket也是一样,所有的东西都在服务器端处理,要怎么复用我想roseforj比wicket更简单灵活。

1 楼 wl95421 2007-08-30  
问几个小问题
1、权限控制是不可避免的问题,怎么处理才能简单呢
2、如何复用


其实我个人感觉这种思路其实并没有超出Velocity或者FreeMarker
但是Tapestry也好,Wicket,甚至是ASP.NET想的不一样
他们考虑的更全面一些
如果是小项目,无所谓
大的项目,考虑的哪怕少一点点,带来的后果都很严重。

相关推荐

    开源web框架Rose开发初感

    综上所述,Rose框架作为一个开源Web开发工具,提供了丰富的功能和工具,通过源码学习和社区支持,开发者可以充分利用它来构建高效的Web应用。同时,通过阅读和分析“lib”目录下的库文件,可以深入理解框架的底层...

    paoding-rose, paoding-rose 提供最好用的Java Web应用整体性框架。.zip

    "最好用的Java Web应用整体性框架"这一描述表明,paoding-rose旨在为开发者提供一套完整的工具集,覆盖了Web应用开发的多个层面,包括但不限于路由分发、数据访问、事务管理、安全控制等。 **开源标签解析** "开源...

    ruby on rose开发文档-开发

    Ruby on Rails,通常简称为Rails,是一个基于Ruby语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在使Web开发更简洁、高效。本开发文档将深入探讨Ruby on Rails的核心概念、关键组件以及常用...

    rose框架使用Demo

    Rose框架,全称为Paoding Rose,是由人人网和糯米网共同推出的开源Java Web开发框架,旨在提供高效的开发体验。它以其简洁的API设计、强大的功能以及良好的性能,在Java开发社区中获得了不少关注。在本文中,我们将...

    Delphi7.Rose项目开发.Part2

    Delphi 7.0 + Rose 项目开发实践

    national rose 和基于C++的软件开发--从理论到实践

    - 基于Rose和C++开发一个小型的游戏引擎,包括角色控制、碰撞检测等功能模块的设计与实现; - 结合UML模型和C++语言特点,开发一款具有复杂逻辑的桌面应用程序。 通过这些案例的学习,读者可以更加深刻地理解如何将...

    Delphi7.0+Rose项目开发实践

    本书以Delphi和Rose软件结合的方式来阐述开发数据库项目的整个过程。书中介绍了数据库项目的多种方法,根据不同的项目采用Rose建模,书中应用的数据库是SQL Server,也可以将其改造成其他数据库系统。本书实例取自...

    Delphi7.0+Rose2003数据库项目开发实践:实例3

    《Delphi7.0+Rose2003数据库项目开发实践:实例3》是一个深入探讨数据库项目开发的教程,结合了两个强大的工具——Delphi 7.0 和 Rational Rose 2003。这个实例系列旨在帮助开发者掌握如何在实际环境中有效利用这两...

    paoding-rose-1.0.1.jar

    "Paoding Rose" 是一个Java Web开发框架,其1.0.1版本的jar包名为"paoding-rose-1.0.1.jar"。这个框架由一系列组件组成,旨在简化Web应用程序的开发过程,提高开发效率。在描述中提到的“包含基本所需要的jar,比较...

    Delphi7.0+Rose2003数据库项目开发实践:实例4

    《Delphi7.0+Rose2003数据库项目开发实践:实例4》是一个深入探讨数据库应用程序构建的教程,特别关注于使用Delphi 7.0集成开发环境(IDE)和Rational Rose 2003建模工具的结合。在本实例中,我们将深入了解如何利用...

    UML和Rose开发

    在Rose开发环境中,有四种主要的视图: 1. **用例视图(Use Case View)**:此视图关注系统的外部行为,主要由用例图组成。用例图描绘了系统与外部参与者(如用户、硬件或其他系统)之间的交互,展示系统功能需求。...

    web开发框架XiaomiRose.zip

    人人网、糯米网释出的、开源的高效Java web开发框架。在小米米聊服务端再次被验证和使用。一个从零开始的创业公司,在大家技术背景不一的情况下,rose很简单快速地传达到了大家中间。本手册致力于让php开发人员也能...

    rational rose2003

    Rational Rose 是一个完全的,具有能满足所有建模环境(Web开发,数据建模,Visual Studio 和 C++ )需求能力和灵活性的一套解决方案。Rose 允许开发人员,项目经理,系统工程师和分析人员在软件开发周期内在将需求...

    paoding-rose备份

    "Paoding Rose" 是一个历史悠久的Java Web开发框架,它主要专注于提高开发效率和提供灵活的URL路由策略。这个备份文件可能包含了Paoding Rose的源代码、文档或者相关的配置文件,便于开发者研究、学习和使用该框架。...

    rose简明教程rose简明教程rose简明教程

    4. **版本支持**:Rational Rose有三个主要版本: - **Rose Modeler**:不支持特定编程语言。 - **Rose Professional**:支持单一编程语言。 - **Rose Enterprise**:支持多种编程语言(如C++、Java、CORBA等)。...

    rose,ROSE安装程序,安装步骤,完整步骤,详细。最全的设置。

    四、ROSE的应用 ROSE广泛应用于软件开发、系统设计和项目管理等领域。ROSE 提供了丰富的功能,包括: 1. 对象oriented设计 2.Unified Modeling Language(UML) 3. Business Process Re-engineering(BPR) 4. ...

    小米 rose Java Web服务器项目源代码

    人人网、糯米网释出的、开源的高效Java web开发框架。在小米米聊服务端再次被验证和使用。一个从零开始的创业公司,在大家技术背景不一的情况下,rose很简单快速地传达到了大家中间。本手册致力于让php开发人员也能...

Global site tag (gtag.js) - Google Analytics