enjoy tempalte 解析多个含有end指令的提示空指针

image.png

image.png

image.png

此处输出流关闭了 提示空指针,这种情况如何处理 ,或是我如何获取content数据而不关闭输出流


image.png



image.png

注释掉charwriter.close 方法后正常    具体没去细看代码  调用10w次左右 为发现io未关闭问题  估计调用 fsw.close 方法的时候就已经关闭了

评论区

JFinal

2020-03-23 16:31

看不出来是哪关闭输出流了

建议像尝试下面的代码:
StringWriter sw = new StringWriter();
String content = template.render(scope.getData(), fsw).toString();

还可以进一步改进:
其实 Template 没必要 new 出来,而是只需要替换输出参数就可以了,例如:
CharWriter charWriter = new CharWriter(64);
FastStringWriter fsw = new FastStringWriter();
charWriter.init(fsw);
try {
stat.exec(env, scope, charWriter);
String content = fsw.toString();
} finally {
charWriter.close();
}

上面的代码,使用你自己 new 出来的 CharWriter 来接管 stat 执行时的输出

JFinal

2020-03-23 16:32

上面的具体用法,参考 com.jfinal.template.ext.directive 包下面的 StringDirective.java

该指定是 #string() ... #end 指令,其中的 exec 方法就用了新的变量接管了输出,并没有向原本的 writer 中输出

chcode

2020-03-23 16:52

impala 不也是sql ? 不知道为啥要自己定义一个指令

goodJfinal

2020-03-23 16:54

@JFinal 找到地方了 更新了帖子 没去具体看这样修改是否有问题 考虑使用你建议方式修改 就是获取输出内容连续性估计有问题 tempalte 我这边不需要缓存 一次性消耗品 应该没关系

goodJfinal

2020-03-23 17:00

@chcode 我这边自己业务做封装 采用哪个数据源执行sql 代码 是靠指令来区分的,具体这边只是个demo代码 大数据方面做数据etl处理的时候 这类东西比较多,但是网上工具大多只做元数据处理 想着使用 enjoy开发个我这边公司的简单etl出来
希望以后数据人员 直接编写 enjoy模板 就能完成 简单工作 比如数据处理到 hive kafka es 等 并具有 记录符合公司规范日志功能

chcode

2020-03-23 17:15

@goodJfinal 我觉得你还不如用namespace去区分呢

JFinal

2020-03-23 18:22

@goodJfinal 区分数据源建议在更高层去区分,而不要在 sql 层面,更不要在 sql 模板层面,太不优雅

用拦截器就是一个很好的切换数据源的办法,在拦截器中只需要根据当前请求账号来切换就可以了,切换的具体代码大至如下:
Account account = getLoginAccount();

String ds = account.getDataSourceName();
Config config = DbKit.getConfig(ds);

// 将 Connection 对象绑定到 ThreadLocal,也就是绑定到当前线程
Connection conn = config.getDataSource().getConnection();
config.setThreadLocalConnection( conn );

try {
inv.invoke();
}
finally {
conn.close();
}


核心在于对当前线程绑定 connection 对象,绑定后,后续的数据库操作都会依赖于这个 connection,而这个 connection 的 DataSource 对象又是与当前登录账号相关联的

杜福忠

2020-03-23 19:01

@JFinal 老大疑问下,将 Connection 对象绑定到 ThreadLocal,如果数据库连接池最大数只有100,请求并发调用该拦截器500次,会被卡住等待着吗?还是getConnection()有什么处理了?

JFinal

2020-03-23 21:34

@杜福忠 connection 资源耗尽后的 getConnection() 会等待,达到最长等待时间会抛异常,最长等待时间之内获取到 connection 后流程继续

不同的连接池实现可能有所不同,druid 中有一个 maxWait 配置最长等待时间,其它连接池不一定有这个

goodJfinal

2020-03-24 09:14

@JFinal 我这个 定位可能并非sql 更多的应该是 定义一个执行流程

热门反馈

扫码入社