阅读更多
全面超越 Velocity 的全新一代 Java 模板引擎 jetbrick-template 1.0.1 正式版发布。

jetbrick-template 是一个新一代 Java 模板引擎,具有高性能和高扩展性。适合于动态 HTML 页面输出或者代码生成,可替代 JSP 页面或者 Velocity 等模板。 指令和 Velocity 相似,表达式和 Java 保持一致,易学易用。

  • 支持类似与 Velocity 的多种指令
  • 支持静态编译
  • 支持编译缓存
  • 支持热加载
  • 支持类型推导
  • 支持泛型
  • 支持可变参数方法调用
  • 支持方法重载
  • 支持类似于 Groovy 的方法扩展
  • 支持函数扩展
jetbrick-template  V1.0.1版改进包括:

完善的中文在线文档:http://subchen.github.io/jetbrick-template/
3
4
评论 共 22 条 请登录后发表评论
22 楼 aasddsasda 2013-11-28 11:44
hellostory 写道
aasddsasda 写道
ide支持是模板引擎的重要组成部分,如果没有优秀的ide插件,强类型的优势无法得到充分体现。
我现在比较喜欢纯JSP(不用jstl和el),语法其实没复杂多少,无非多打几个<%%>,IDE支持非常完善,语法检查、自动完成、重构等都是小意思,性能和java硬编码一致。如果用在非web环境可以自己写个引擎,因为JSP完全遵循java语法规范,引擎实现起来会非常容易。
<table>
<%for(User user : user){%>
  <tr>
    <td><%=row.getId()%></td>
    <td><%=row.getName()%></td>
    <td><%=row.getAge()%></td>
    <td><%=row.getType()%></td>
  </tr>
<%}else{%>
  <tr><td>无数据</td></tr>
<%}%>
</table>


EL大多数都支持!

使用原始JSP何止多打几个<% %>!

日期格式化、数字格式化,这些需求千变万化,你能在一个<% %>搞定?你需要多写几行网页设计师看不懂的JAVA代码,还是都在后台加工?



EL是弱类型的,所以IDE无法进行强类型检测,自动提示什么的也根本不可能,这失去了java静态语言健壮严谨的特性。而且编译后是解释执行的,多少会影响性能,可以说EL没有带来什么好处!

格式化等问题,<%=Util.fmt(user.getDate(),"yy-mm-dd")%>这样写有什么不同?
甚至可以使用jsp的继承功能,将工具函数写到jsp父类中,import都免了,直接写<%=fmt(...)%>就行了。

如果说网页设计师看不懂<%%>,一样也看不懂<fmt:formatDate>是什么,实际项目中前端最多也就到html这步,最终还是要由后端负责生成模板不是吗
21 楼 hellostory 2013-11-28 10:34
aasddsasda 写道
ide支持是模板引擎的重要组成部分,如果没有优秀的ide插件,强类型的优势无法得到充分体现。
我现在比较喜欢纯JSP(不用jstl和el),语法其实没复杂多少,无非多打几个<%%>,IDE支持非常完善,语法检查、自动完成、重构等都是小意思,性能和java硬编码一致。如果用在非web环境可以自己写个引擎,因为JSP完全遵循java语法规范,引擎实现起来会非常容易。
<table>
<%for(User user : user){%>
  <tr>
    <td><%=row.getId()%></td>
    <td><%=row.getName()%></td>
    <td><%=row.getAge()%></td>
    <td><%=row.getType()%></td>
  </tr>
<%}else{%>
  <tr><td>无数据</td></tr>
<%}%>
</table>


EL大多数都支持!

使用原始JSP何止多打几个<% %>!

日期格式化、数字格式化,这些需求千变万化,你能在一个<% %>搞定?你需要多写几行网页设计师看不懂的JAVA代码,还是都在后台加工?

20 楼 git_for_java 2013-11-28 09:00
mark 貌似功能很强大,文档很清晰。
19 楼 aasddsasda 2013-11-25 13:06
ide支持是模板引擎的重要组成部分,如果没有优秀的ide插件,强类型的优势无法得到充分体现。
我现在比较喜欢纯JSP(不用jstl和el),语法其实没复杂多少,无非多打几个<%%>,IDE支持非常完善,语法检查、自动完成、重构等都是小意思,性能和java硬编码一致。如果用在非web环境可以自己写个引擎,因为JSP完全遵循java语法规范,引擎实现起来会非常容易。
<table>
<%for(User user : user){%>
  <tr>
    <td><%=row.getId()%></td>
    <td><%=row.getName()%></td>
    <td><%=row.getAge()%></td>
    <td><%=row.getType()%></td>
  </tr>
<%}else{%>
  <tr><td>无数据</td></tr>
<%}%>
</table>
18 楼 subchen 2013-11-25 09:11
skzr.org 写道
subchen 写道

不同的测试环境是有一些波动的,测试结果只能作为参考,建议你可以下载最新的测试代码 https://github.com/subchen/ebm 在自己的机器上进行测试。


今天增加了jetbrick的测试,之前我测试的velocity慢是因为没有启用cache默认是关闭的。测试结果:
参数:(-server -Xms1g -Xmx1g):
测试项目    引擎  生成次数    总耗时   平均耗时    1s处理
TABLE   FM  130K    10.303s 0.079ms 12617
TABLE   JT  130K    3.022s  0.023ms 43017
TABLE   VM  130K    9.642s  0.074ms 13482

velocity相比freemarker微弱的优势胜出。

今天第一次用jetbrick,和之前我们平台研发部的模板引擎思路一样静态编译页面,从以前的开发使用体验上看,要做好非常困难,最大的难点:模板语言到java语言翻译,必然牺牲了模板语言的灵活性,需要迁就java的强类型。

开发体验上:
  • 开发调试时非常郁闷
  • 很多在其他模板语言中常见的语法,写起来非常别扭


最后我的测试工程:https://github.com/takeseem-com/test-template


看了你的测试, jetbrick-template 支持 #for-#else 组合哦,可以这么用

<table>
#for(Map row : rows)
  <tr>
    <td>${row.id}</td>
    <td>${row.col1}</td>
    <td>${row.col2}</td>
    <td>${row.size()}</td>
  </tr>
#else
  <tr><td>无数据</td></tr>
#end
</table>

关于你的疑问:
1. 目前没有碰到调试问题,jetbrick-template 提供丰富的模板错误信息来定位错误原因,并且可以用生成的 java source来帮助断点调试(这个是Velocity,Freemark等模板不具备的)
2. 关于强类型要求的类型声明,这个目前在实际项目中要求什么的变量并不是很多,大部分都是通过类型推导来获取。只有在类型推导失败的情况下才需要定义 #define。
17 楼 subchen 2013-11-25 09:00
skzr.org 写道
第一次用时,文档展现形式很好,还是有点不方便,有个类似freemarker的A-Z index文档就完美了。
吐槽下,velocity文档比较晦涩。
velocity和jet都是我第一次用 :)


感谢你的意见和建议。由于 jetbrick-template 没有Freemarker那么复杂的指令和API,都比较简单,暂时不需要A-Z Index,当然文档的目录结构会进一步改善。
16 楼 skzr.org 2013-11-24 23:52
第一次用时,文档展现形式很好,还是有点不方便,有个类似freemarker的A-Z index文档就完美了。
吐槽下,velocity文档比较晦涩。
velocity和jet都是我第一次用 :)
15 楼 skzr.org 2013-11-24 23:46
subchen 写道

不同的测试环境是有一些波动的,测试结果只能作为参考,建议你可以下载最新的测试代码 https://github.com/subchen/ebm 在自己的机器上进行测试。


今天增加了jetbrick的测试,之前我测试的velocity慢是因为没有启用cache默认是关闭的。测试结果:
参数:(-server -Xms1g -Xmx1g):
测试项目    引擎  生成次数    总耗时   平均耗时    1s处理
TABLE   FM  130K    10.303s 0.079ms 12617
TABLE   JT  130K    3.022s  0.023ms 43017
TABLE   VM  130K    9.642s  0.074ms 13482

velocity相比freemarker微弱的优势胜出。

今天第一次用jetbrick,和之前我们平台研发部的模板引擎思路一样静态编译页面,从以前的开发使用体验上看,要做好非常困难,最大的难点:模板语言到java语言翻译,必然牺牲了模板语言的灵活性,需要迁就java的强类型。

开发体验上:
  • 开发调试时非常郁闷
  • 很多在其他模板语言中常见的语法,写起来非常别扭


最后我的测试工程:https://github.com/takeseem-com/test-template
14 楼 subchen 2013-11-24 21:37
skzr.org 写道
subchen 写道
skzr.org 写道
qiuguo0205 写道
文档很好啊,支持,加油

文档有模有样,看了性能测试部分,感觉太夸张了点。

之前选择规则引擎时测试过,感觉freemarker不应该这么慢的?
我的测试结果在这里:
https://github.com/takeseem-com/test-template/tree/0.1

测试出来的结果(fm和vm的比较)正好和文档中的相反。
我认为作为基本测试,不应该启动多个vm来测试,这样对于他们不公平。


在不同的 vm 中测试是为了保证公平,因为jvm对于同一段代码运行的次数越多,性能会越好。


这个带来性能的提升很少的,你加上-server实际上他们就相同了。我只是非常奇怪,你们怎么得出velocity比freemarker快将近一倍,而我测试出来的和你们的结果却是相反的。



不同的测试环境是有一些波动的,测试结果只能作为参考,建议你可以下载最新的测试代码 https://github.com/subchen/ebm 在自己的机器上进行测试。
13 楼 skzr.org 2013-11-24 21:33
subchen 写道
skzr.org 写道
qiuguo0205 写道
文档很好啊,支持,加油

文档有模有样,看了性能测试部分,感觉太夸张了点。

之前选择规则引擎时测试过,感觉freemarker不应该这么慢的?
我的测试结果在这里:
https://github.com/takeseem-com/test-template/tree/0.1

测试出来的结果(fm和vm的比较)正好和文档中的相反。
我认为作为基本测试,不应该启动多个vm来测试,这样对于他们不公平。


在不同的 vm 中测试是为了保证公平,因为jvm对于同一段代码运行的次数越多,性能会越好。


这个带来性能的提升很少的,你加上-server实际上他们就相同了。我只是非常奇怪,你们怎么得出velocity比freemarker快将近一倍,而我测试出来的和你们的结果却是相反的。
12 楼 subchen 2013-11-24 20:16
skzr.org 写道
qiuguo0205 写道
文档很好啊,支持,加油

文档有模有样,看了性能测试部分,感觉太夸张了点。

之前选择规则引擎时测试过,感觉freemarker不应该这么慢的?
我的测试结果在这里:
https://github.com/takeseem-com/test-template/tree/0.1

测试出来的结果(fm和vm的比较)正好和文档中的相反。
我认为作为基本测试,不应该启动多个vm来测试,这样对于他们不公平。


在不同的 vm 中测试是为了保证公平,因为jvm对于同一段代码运行的次数越多,性能会越好。
11 楼 skzr.org 2013-11-23 01:27
既然测试代码开源,还是改为maven的标准吧,lib都自己维护太坑了。
同时为啥你们要关闭项目的issue。
10 楼 skzr.org 2013-11-23 01:25
qiuguo0205 写道
文档很好啊,支持,加油

文档有模有样,看了性能测试部分,感觉太夸张了点。

之前选择规则引擎时测试过,感觉freemarker不应该这么慢的?
我的测试结果在这里:
https://github.com/takeseem-com/test-template/tree/0.1

测试出来的结果(fm和vm的比较)正好和文档中的相反。
我认为作为基本测试,不应该启动多个vm来测试,这样对于他们不公平。
9 楼 ufopw 2013-11-22 11:57
maoweiwer 写道
hellostory 写道
qiuguo0205 写道
文档很好啊,支持,加油


请问除了支持和加油外,你还会为它做什么?


带着浓浓的疑问质疑语气问别人。那么请问你又做了什么?

会质疑
8 楼 maoweiwer 2013-11-22 09:04
hellostory 写道
qiuguo0205 写道
文档很好啊,支持,加油


请问除了支持和加油外,你还会为它做什么?


带着浓浓的疑问质疑语气问别人。那么请问你又做了什么?
7 楼 hellostory 2013-11-21 13:32
qiuguo0205 写道
文档很好啊,支持,加油


请问除了支持和加油外,你还会为它做什么?

6 楼 非法用户 2013-11-21 13:11
搞技术跟创业是一个道理吧,现在搞出来已经没啥市场了
5 楼 qiuguo0205 2013-11-21 12:01
文档很好啊,支持,加油
4 楼 yixiandave 2013-11-21 11:29
现在感觉还是前后端分离比较好,中间交互全部json

模板什么的去死吧!!!
3 楼 nomandia 2013-11-21 10:33
早就恨透了各种java模板,完完全全!

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • BCB建立及调用DLL

    自己再网上看到的帖子,用C++builder 6.0调试了下,更正了其中两个容易出现的dug.

  • BCB中动态链接库的建立和调用

    1.创建DLL工程 文件-&gt;新建-&gt;其他-&gt;DLL Wizard,单击确定后,source type选择C++,单击ok。在文件的末尾写入自己的代码(这里以调用PO法计算RCS函数为例,复制了旧工程中)如下图1所示。(注意:__declspec,__fastcall这里的横线是两个横线组成) 图1 建立DLL并在文件末尾输入代码 2.生成DLL和LIB文件 注意:在写入代码后,有一些该函数中调用的但是本工程中没有的函数、变量以及一些头文件要加上去,不然运行时会报错,加的函.

  • BCB如何编写,调用动态链接库DLL

    一 编写动态链接库DLL DLL简称动态链接库,是Windows中程序的重要组成部分。想象一下,一个程序需要多人共同完成开发,怎么个共同法?这时我们就要考虑把程序分为好几个模块,团队每一个成员开发一个模块。问题来了:如何将模块组合并成一个完整系统?还有,我们开发的软件需要不断升级,如何升级?难道每次非得把整个工程重新编译一次再发布给用户吗?解决这些问题的科学办法,就是开发动态链接库DLL。现在

  • 怎样在C++Builder中创建使用DLL

    动态链接库(DLL)是Windows编程常遇到的编程方法,下面我就介绍一下在 BCB (C++Builder下简称BCB) 中如何创建使用DLL和一些技巧。   一、创建:   使用BCB File|NEW建立一个新的DLL工程,并保存好文件BCB,生成一个DLL 的程序框架。   1.DllEntryPoint函数为一个入口方法,如果使用者在DLL被系统初始化或 者注销时

  • 设置dll的共享数据段

    BCB直接在DLL中定义共享内存单元的步骤如下:    假设DLL的工程名为MouseHook.bpr(编译后产生MouseHook.DLL)       1.在一程序模块 Unit1.cpp的最前面加上:            #pragma option -zRSHSEG      // 改变缺省数据段名            #pragma option -zTSHCLASS    

  • BCB6 调用C# DLL

    最近项目涉及第三方接口调用。第三方是用C#实现的WCF服务。而我们的程序是使用的BCB6开发。因此,打算将与WCF的通讯包含在C#的类库中,给BCB6调用。BCB6 是无法直接调用C#的DLL,但可以通过C#编写一个COM组件,然后BCB调用这个COM组件来调用。 用C#编写COM 大体步骤是 新建一个类库项目 ...

  • __stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介

    __stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介 1.今天写线程函数时,发现msdn中对ThreadProc的定义有要求:DWORD WINAPI ThreadProc(LPVOID lpParameter); 不解为什么要用WINAPI宏定义,查了后发现下面的定义。于是乎需要区别__stdcall和__cdecl

  • c语言dll bcb,BCB编写DLL终极手册

    一. 编写 DLLFile/New/Dll 生成 Dll 的向导,然后能够添加导出函数和导出类导出函数:extern "C" __declspec(dllexport) ExportType FunctionName(Parameter)导出类:class __declspec(dllexport) ExportType ClassName{...}例子:(说明:只是生成了一个 DLL.dll )...

  • C++文件说明及使用方法

    C++文件说明及使用方法库文件VS2015中导入文件说明 C++/C程序编译的过程可以粗分为两个阶段:编译和链接;编译又可以分为 预处理、编译、汇编三个阶段 在编写编译C++的过程中有很多种文件,例如源文件,头文件,静态库文件,动态库文件等。每种类型的文件都有其存在的意义 库文件 库是一些函数和类的集合,其实现了某些特定的功能,是程序的开发免于从头开始。 库有两种:静态链接库和动态链接库!在windows下静态链接库为.lib,动态链接库为.dll;Linux下静态链接库为.a,动态链接库为.so。这里我

  • c++ builder(BCB)中DLL的创建与调用

    1、DLL创建 File-&gt;New-&gt;Other,选择C++ builder-&gt;Dynamic Library,选择C++,Visual ComponentLibrary。 2、DLL的代码输写 主头文件,声明和定义导出结构体 主CPP文件,写导出函数定义,导出函数用 extern "C" 声明,加 __declspec(dllexport) 修饰,函数名前加__stdcall修饰表示Windows API默认调用方式。 如下: extern "C"__declspe..

  • BCB编写DLL终极手册(写给新手)

    BCB编写DLL终极手册 一. 编写 DLL File/New/Dll 生成 Dll 的向导,然后可以添加导出函数和导出类 导出函数:extern "C" __declspec(dllexport) ExportType FunctionName(Parameter) 导出类:class __declspec(dllexport) ExportType ClassName{...} 例子:(说明

  • BCB实现DLL简单demo

    主要分为两个部分:创建DLL文件,调用DLL文件。 Note: BCB运行环境:2010 C++ Builder XE 创建DLL文件 Step1 创建DLL Project a.1双击BCB软件,接着依次选择:File→New→Other,跳出如下dialoguebox: a.2或者在右侧点击,add new project,跳出如下dialoguebox: b. 选择“Dy...

  • BCB动态库和OCX里面CM_MOUSELEAVE和CM_MOUSEENTER消息的实现

    由于改造封装一个BCB的OCX,在MFC里面调用,导致原来许多使用的CM_MOUSELEAVE和CM_MOUSEENTER消息失效, 这两个消息是VCL的自定义消息,依赖于VCL的消息循环,源于TApplication.DoMouseIdle方法, 而该方法由TApplication.Idle调用,Idle是TApplication.HandleMessage的消息处理循环的一部分。 最终H

  • BCB(C++ Builder)创建动态库(DLL,接口导出和调用),动态加载DLL

    以前没有封装dll动态库,接触新的工作之后需要用,折腾了一整天,终于搞定了 毕竟是生手,就简单分析注意点和遇到的一些问题及解决方案: (1)首先准备要生成DLL的工程。 (1.1)我用的是BCB(C++ Builder),File-&gt;New-&gt;Other...-&gt;C++ Builder Projects-&gt;Dynamic-Link Library,再根据之后的提示进行...

  • BCB 调用DLL

    HINSTANCE Hdl; int __stdcall (*ShowPage)();//定义函数原型 AnsiString disExeFile = ExtractFileDir(Application-&amp;gt;ExeName)+"\ProjectDLL.dll"; Hdl = ::LoadLibrary(disExeFile.c_str()); /...

  • C++Builder 6 [BCB6] 共享数据段 错误 测试 (bug 、[Linker Error] Section SHSEG defined in .def file is empty)

       这个话题,可以说网上绝对没有一个帖子或者答案是齐全的,是让人信服的。更有些都是摘抄的BCB4的一些论坛上的   我花了4个小时,对BCB的共享数据段做了一些较浅,易懂的测试。网上的一些帖子LZ说自己解决了,然后还给了很多自己的看法,大多数都是有问题,或者是断章取义的。   比如以下是一个作者给出的编译成功的条件:   1)ShareUnit.cpp文件中必须用struct,(2)

Global site tag (gtag.js) - Google Analytics