2017-08-15 11:14

jdk 也是在不断升级的,而升级的过程中,以 sun 打头的那些 java 类可能会被删掉,例如 java 8 中就没有 sun.io.ByteToCharConverter

找一下 db2 的针对 java 8 的驱动,或许就解决了,驱动也是不断升级的

2017-08-14 22:33

对 jfinal template engine 的理解与使用已经到了非常深刻的程度,各种用法包括 layout、自定义指令、shared object 等等,并且可以将 jsp 的自定义tag 迁移过来,这种用法十分具有参考价值

感谢你的分享,不枉我花了这么多时间啊

2017-08-14 21:27

handler 搞定后,配置一下: me.add(new UrlHandler())

这种方式用得很广泛,几年前我就用这种方式做过网站的老 url 映射到新 url 的 302 重定向,将搜索引擎以前收录的 url 转到新的 url 之上

2017-08-14 21:25

@lyq027 用一个 UrlHandler 做个转换就可以了,大致如下:
1:v1、v2、... vn 当成是参数来处理
2:这类 url 通过 UrlHandler 全转换为指向 ApiController
3:转换方式为 "/api/v*/method?params" 转成 "/api/method/v*?paras
4:转换完成以后,通过 getPara(0) 即可获取到 "v1"、"v2"、..."vn" 这类参数值

转换代码可以通过正则,也可以通过简单的字符串处理代码:
public void handle(String target, req, resp, isHandled) {
if (target.startsWith("/api/v")) {
String prefix = target.substring(0, 4);
String post = target.substring(7);
String version = target.substring(5, 6);
target = prefix + post + "/" + version;
}
next.handle(target, req, resp, isHandled);
}

当然,为了简单性上面代码假定了你的版本号为 2 个字符,需要你自己调整,在此仅为示例

简单一句话,就是将 target 转换成指向正确 action 的 url 值就好

2017-08-14 19:12

v1 是指路由中的哪部分? 是否是参数,如果是 actionKey 的一部分,可以在拦截器中通过 inv.getActionKey() 整体获取

2017-08-14 19:11

cos.jar 这个包,在首页下载 jfinal-3.2-all.zip , 里面有

2017-08-14 17:38

@ThreeX 我倒是建议,直接用绝对路径:
renderTemplateToString("/path/file.html");

这类方法使用应该不多,偶尔不用 viewPath 还可以,除非你大量在用这个方法

2017-08-14 17:36

Inject 是否需要区分一下 byName 还是 byType ?

最大的问题是这句:
Object fieldValue = Class.forName(field.getType().getName()).newInstance();

如果 Field 是个接口或者抽象类,这里肯定就异常了,无法被实例化,而且这里的创建方式没有体现被实例化的“实现类”的动态特性,不如 new 出来方便

2017-08-14 17:28

最后将 ViewPathInterceptor 配置为全局拦截器就好。 如果没有使用 BaseController,可以通过 inv.getController().setAttr("viewPath", ...) 传递也可以

2017-08-14 17:27

建议用一个拦截器辅助来做一下,添加一个拦截器,并通过如下代码将 viewPath 存放在 ThreadLocal 中:
public ViewPathInterceptor implements Interceptor {
private static final ThreadLocal threadLocal = new ThreadLocal();

public void intercept(Invocation inv) {
threadLocal.set(inv.getViewPath);
try {
inv.invoke();
} finally {
threadLocal.remove();
}
}

public static String getViewPath() {
return threadLocal.get();
}
}

然后在 BaseController extends Controller 中覆盖掉原先的 renderTemplateToString 方法,先通过 ViewPathInterceot.getViewPath() 获取到 viewPath,然后再与 template 参数组合一下即可

2017-08-14 17:15

@咔嚓 在本站首页右侧下载 jfinal 手册,其中有一章内容专门讲了模板引擎的用法

2017-08-14 16:53

@昔竹 如果是 debug , 这是正常的调试信息不需要理会,否则应该是缺包, 把缺少的包找对了就搞定了

2017-08-14 16:03

查询参数通常是 Object... paras, 我不记得有 list 为参数的

第二个问题不知道问的是什么,但建议你尽保能用问号占位来写 sql

2017-08-14 16:01

补充一下,添加一个你建议的 Engine.getTemplateByString(key,content) 方法也是可以的,但如我前面所说 engine 默认行为已经能够应对绝大部分场景,并且在极端情况下也可以很方便使用 true 参数,或者扩展 ISource 接口,所以也就没有添加这个方法,在保障大部分场景,又满足了完备性的同时,能省则省了

当然,这个问题一直是保持开放的,将来认知的提升,以及用户需求与反馈的消息过来以后,随时可以添加新的支持,你的建议也随时可以被添加进来

2017-08-14 15:56

由于 jfinal 是自己写算法来解析模板,所以解析性能是 freemarker、velocity 的 6 倍,这个性能在绝大多数场景下都是足够的,对于一个普通的模板文件解析时间都只需要几个毫秒,更何况这类 String 的内存对象,解析时间几乎可以忽略不计。

因此,jfinal 3.2 对 String 内存型的模板默认采用了不缓存的策略。而只有在极端情况下才需要缓存,这时候开发者可以使用 getTemplateByString 的 true 参数进行缓存,这种情况适用于 String 型的模板个数是有限的,不会造成内存泄漏

如果对性能有极端要求,同时 String 型模板的个数是不确定的,那么可以通过实现 ISource 接口去解决,该接口中有一个 getKey() 方法,可以用于指定缓存的 key,下面是一个大致的例子:
public class StringTemplate implements ISource {
private String key;
private String content;
public StringTemplate(String key, String content) {
this.key = key;
this.content = content;
}

public String getKey() {
return key;
}
// 其它实现方法省略
}

在用的时候这样:
engine.getTemplate(new StringTemplate(key, content));