2017-06-29 11:53
这个需要了解一下 http 协议的 multipart 请求规范,http 表单提交主要有两类:
1:普通表单提交,即普通的 request 请求
2:multipart request 表单提交
特别注意第二种提交是上传文件必须的提交类型,需要为 form 表单设置 enctype="multipart/form-data" 属性
第二种表单提交到服务器以后的 HttpServletRequest 对象是不能直接 request.getParameter(...) 的,因为里头的数据没有被解析
这时各种 file 解析的第三方就上场了,例如 cos、fileupload 这类项目,还有很多这种:https://www.oschina.net/project/tag/139/fileupload?company=0&sort=score&tag=139&lang=19&recommend=false
所以,当请求是 multipart 时,必须要对 request 这个对象进行解析,才可以让 request.getParameter(...) 得到数据
而 jfinal 对 multipart 的解析在 getFile(...) 这类方法中进行,所以需要首先调用 getFile(...) 随后才可以调用 getPara(...),本质就是要先解析,才可以 getPara(...),这个问题在 jfinal 手册上有红色字体说明
当然,jfinal 可以在框架内部自动判断请求是否为 multipart 请求,然后自动事先解析,那么用户就不需要关心 getFile 是在前还是在后的问题了,但会引发两个问题:
1:getFile(path, ...) 方法可以传入一个 path 参数,用于指令解析出来的文件存放在哪里,如果 jfinal 帮忙去调用 getFile(...),是无法得到这个 path 参数的。
如果 jfinal 一定要插手此事,只能是先存放在一个固定的临时目录,然后由用户随后自己再手动移动该文件
2:jfinal 需要在每次请求到来时都去判断请求是否为 multi part 类型,而这种请求实际上极少发生,为了极少发生的事情,每每去判断,多少会损失点性能
综上,设计是一个不断权衡取舍的过程,很多纠结
2017-06-29 11:41
@九块腹肌进先生 jfinal 这端的 getPara(...) 仅仅是转调了底层 HttpServletRequest requset 对象的 getParameter(...) 方法,没有任何多余的动作,是不可能出错的
建议你查看一下控制台输出的 jfinal action report 数据中的其中有关 parameter 这一栏,是否有参数过来
这个问题基本可以确定是客户端的事情,getPara(...) 是最基本的功能调用,使用了六年多时间了,绝对不可能出错
2017-06-29 11:38
@david__ #@layout() 是调用模板函数,一定要理解为将定义为 #define layout() 的模板拿进来也可以
总结一下:
1:定义
#define funcName()
body
#end
2:调用
#@funcName()
2017-06-28 21:16
@阿亮 现在已做成了分支,直接可用: https://github.com/jfinal/jfinal/tree/jfinal-java8
注意要使用 java8,并将 eclipse 编译参数打开保留形参名
2017-06-28 17:58
@caoxusheng 这个错误提示与 "./" 没有关系,参考一下这里:http://zhaoningbo.iteye.com/blog/1137215
2017-06-28 11:30
很早以前碰到过几个小伙伴也这么来玩的,后来慢慢也改成严格的 MVC 走 action了,因为纯静态页面很少很少,多数是要在页面中使用动态数据的,如果直接走页面,势必要在页面中通过某种方式再去访问数据,这种结构不如 MVC 清晰好维护
当然,在 jfinal 下是很容易支持这种模式的,你甚至可以只有页面和一些工具类,大致这么来玩:
1:创建一个 Handler 用于接管所有请求,将请求直接生成String templateFile 这个对象指向模板文件,大致如下:
public void handle(target, req, res, isHandled) {
String templateFileName = buildTemplateFileName(target);
Engine.use().getTemplate(templateFileName).render(...);
isHandled[0] = true;
}
2:创建一些用于操作数据库的工具类,或者直接用 jfinal 的数据库工具类配置给 Engine
Engine.use().addSharedObject("Db", Db.use());
3:在页面可以这样用了:
#for ( x : Db.find("select * from account where ..." ...))
#(x.userName)
#end
通过上面的方式,你可以完全避免掉 Controller、Interceptor、Render 等所有的东东,一般我不告诉小伙伴们这么来玩