2022-09-29 11:01

@杜福忠 业务封装非常深入,对 enjoy 的灵活运用趋向极致

2022-09-28 20:55

@杜福忠 json 配置 UI 怎么玩的? 贴点代码出来看看

2022-09-28 20:54

@杜福忠 我觉得你这个方向很有前景,业务逻辑才是应用软件的核心,UI 尽可能最低成本最高效率实现是大势所趋,UI 在未来都该组件化

2022-09-28 20:51

很多同学需要生成 table 注释,非常有用的分享,收藏 + 点赞一波

2022-09-25 20:04

@zzutligang 对每个方法都去父类拿它的注解,而父类还有可能有父类,代价太大

而这个需求几乎无人提及

你在子类中不使用 @Before 覆盖父类的是自动拿到的,使用 @Before 以后要注意将父类的拦截器一并放在当前方法

2022-09-24 23:26

@Leo.du @杜福忠 试用一下我这个设计,代码量一定要少,充分利用指令扩展的强大能力

2022-09-24 23:26

你的实现思路是非常好的,但是代码量有点多了,我刚刚写了一个版本,你试用一下:
1: 定义一个 #template 指令,该指令至少需要一个参数传递模板名,其它参数可任意,例如可传递赋值表达式传值进去:#template("template.txt", title="enjoy")
public class TemplateDirective extends Directive {

@Override
public void setExprList(ExprList exprList) {
if (exprList.length() < 1) {
throw new ParseException("#template 指令至少需要 1 个参数", location);
}
super.setExprList(exprList);
}

@Override
public void exec(Env env, Scope scope, Writer writer) {
if (scope.getRootData() == null) {
scope.setRootData(new HashMap());
}

// 将指令内部的全部内容传递给 #slot 指令去使用
Object[] values = exprList.evalExprList(scope);
String templateFile = values[0].toString();
scope.getRootData().put("__slotStat__", stat);

// 指令自身直接渲染参数传递的模板就行
StringBuilder sb = Engine.use().getTemplate(templateFile).renderToStringBuilder(scope.getRootData());
write(writer, sb.toString());
}

public boolean hasEnd() {
return true;
}
}

2: 定义一个 #slot 插槽指令
public class SlotDirective extends Directive {

@Override
public void exec(Env env, Scope scope, Writer writer) {
Object slotStat = scope.getRootData().get("__slotStat__");
if (slotStat == null) {
throw new TemplateException("slotStat 未找到", location);
}

if (slotStat instanceof Stat) {
((Stat)slotStat).exec(env, scope, writer);
}
}
}


测试代码:
1: 模板文件 template.txt 的内容如下:
AAA
#slot()
ZZZ

2: 测试用的主模板 test.txt 内容如下:
#template("template.txt")
#for (x : [0..3]) #(x) #end
#end

3: java 测试代码如下
public class Test {
public static void main(String[] args) {
Engine.use().setToClassPathSourceFactory();
Engine.use().addDirective("template", TemplateDirective.class);
Engine.use().addDirective("slot", SlotDirective.class, true);
String ret = Engine.use().getTemplate("test.txt").renderToString(Kv.create());
System.out.println(ret);
}
}

2022-09-24 21:51

这是 java 语法决定的,子类可以继承父类声明的注解,前提是你在子类中没有覆盖掉它

2022-09-22 18:29

俱乐部有提供 enjoy 的设计、算法、源码的解读:
enjoy设计-算法-源代码.mp4
enjoy设计-算法-源代码.pptx

下载地址:
https://jfinal.com/my/club

2022-09-22 12:03

基本照抄 enjoy 的 Lexer、Parser、ExprLexer、ExprParser 就可以了

词法分析是通用的,大学教材编译原理里面有。语法分析是递归下降,编码原理里面也有

enjoy 对词法、语法解析有所改进,改成了双层,在指令上用了一层,在表达式层央用了一层

单步调试能搞懂细节

2022-09-18 12:36

@chcode enjoy 极简设计之下,添加这个功能添加一行删除一行代码的事,这就是极简设计的力量:

https://gitee.com/jfinal/jfinal/commit/00940a2a2390932cf95a871a65b2172a1341dca8

2022-09-13 21:31

当然,现在 JFinalJson 也提供一配置方法可以自动转换

2022-09-13 21:31

字段名用驼峰在 mysql 中是可以的

数据库用驼峰,省很多事,不用转换来转换去

2022-09-13 21:30

开启 gzip 压缩或者采用 nginx 代理后会无法显示 content length,解决办法如下:
https://www.jianshu.com/p/946340a803dd

2022-09-07 18:31

不支持位运算、二进制,文档中有过说明:
https://jfinal.com/doc/6-3

15、从java中去除的运算符
针对模板引擎的应用场景,去除了位运算符,避免开发者在模板引擎中表述过于复杂,保持模板引擎的应用初衷,同时也可以提升性能。

与位运算、二进制有关的都不支持,事实证明,你是第一个提起这件事的

如果你要支持,可以通过 sharedObject、sharedMethod 扩展支持,打通到后端的 java , 让 java 支持就行了

例如,以下通过sharedMethod 扩展实现与运算
#( bitAnd( 123, 456 ) )

java 代码这么写:
public int bitAnd( int a, int b ) {
return a & b;
}

最后配置一下:
engine.addSharedMethod(...);