@JFinal 你好,我发现了一些很有趣的事情,
1.在使用POST上传文件及文本参数时,后台要获取文本参数,必须先获取文件,不然文本参数为null,测试代码如下:
public void testPost() { getFile(); String a = getPara("a"); renderText(a); }
2.接口仅需要上传文本参数时,如果使用GET方式,后台可正确接收到文本参数,但使用POST方式时,后台获取的文本参数将为null,代码如下:
使用get可接收到文本参数:
public void testGet() { String a = getPara("a"); renderText(a); }
当使用POST方式时,将获取不到文本参数,尽管此时我没有上传文件,但为了获取到文本参数,我必须手动调用一下getFile()方法,才能成功获取:
public void testGet() { getFile(); String a = getPara("a"); renderText(a); }
但是因为加上了getFile(),我再想使用GET调用时,就会报异常:
java.lang.RuntimeException: java.io.IOException: Posted content type isn't multipart/form-data
程序会默认其为POST调用的,content type类型不正确,此时,此接口将不能使用GET调用。
即:POST,GET不能共存。
因为处于项目开发阶段,时间有限,所以没深入探究源码,请问,为什么会造成这种现象,有没有何种解决方式?
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 类型,而这种请求实际上极少发生,为了极少发生的事情,每每去判断,多少会损失点性能
综上,设计是一个不断权衡取舍的过程,很多纠结