jfinal 临时文件下载(用户下载完成后删除服务器的文件)
2014-05-16 20:27
218 查看
本人在使用jfinal做一个项目的时候,需要下载一些临时文件,就是有程序产生,并且被用户下载后就失效的小文件,在使用jfinal的
查看jfinal controller的renderFile源码后发现,调用render系列方法后,并没有马上执行render操作,代码如下:
由此可见,renderFile只不过是产生了一个render对象而已,这样就能解释了,因为调用renderFile后我们把文件删除了,于是就无法下载了,于是继续找,然后找到调用这个方法的地方,发现是在一个叫做
我们发现在
问题已经找到了,于是我们需要解决,刚开始问群里的时候,大家都是建议使用定时删除,队列的方式来执行,我个人不喜欢这种绕圈子的做法,于是有了方案1
这种代码解决了问题,但是还是不够好,我相信大部分人也不喜欢这种方式,虽然可以封装一个方法去做这个事情.后来用了一种更好的方式来解决这个问题,而且比较符合jfinal的设计哲学
由于jfinal已经有了FileRender,我们可以直接继承它,我们重写 render方法就好了,这种方法做到了代码重用,个人很喜欢,代码如下:
这样在controller中使用就只需要
打完收工
renderFile(file);后,调用 file.delete();发现,文件无法下载,于是找问题
查看jfinal controller的renderFile源码后发现,调用render系列方法后,并没有马上执行render操作,代码如下:
/** * Render with file */ public void renderFile(String fileName) { render = renderFactory.getFileRender(fileName); } /** * Render with file */ public void renderFile(File file) { render = renderFactory.getFileRender(file); }
由此可见,renderFile只不过是产生了一个render对象而已,这样就能解释了,因为调用renderFile后我们把文件删除了,于是就无法下载了,于是继续找,然后找到调用这个方法的地方,发现是在一个叫做
ActionHandler的了类里面,找到这个类的handler方法,关键部位代码如下:
Controller controller = action.getControllerClass().newInstance(); controller.init(request, response, urlPara[0]); if (devMode) { boolean isMultipartRequest = ActionReporter.reportCommonRequest(controller, action); new ActionInvocation(action, controller).invoke(); if (isMultipartRequest) ActionReporter.reportMultipartRequest(controller, action); } else { new ActionInvocation(action, controller).invoke(); } Render render = controller.getRender(); if (render instanceof ActionRender) { String actionUrl = ((ActionRender)render).getActionUrl(); if (target.equals(actionUrl)) throw new RuntimeException("The forward action url is the same as before."); else handle(actionUrl, request, response, isHandled); return ; } if (render == null) render = renderFactory.getDefaultRender(action.getViewPath() + action.getMethodName()); render.setContext(request, response, action.getViewPath()).render();
我们发现在
new ActionInvocation(action, controller).invoke();后才去执行的render方法,
render.setContext(request, response, action.getViewPath()).render();
问题已经找到了,于是我们需要解决,刚开始问群里的时候,大家都是建议使用定时删除,队列的方式来执行,我个人不喜欢这种绕圈子的做法,于是有了方案1
方案1
自己写代码去renderFile,这样就可以避免这个问题了,代码大致如下(基本上是从FileRender类中拷贝而来):
String contentType = getRequest().getServletContext().getMimeType(file.getName()); if (contentType == null) { contentType = "application/octet-stream"; // "application/octet-stream"; } System.out.println(contentType); getResponse().setContentType(contentType); getResponse().setContentLength((int) file.length()); OutputStream out = getResponse().getOutputStream(); FileInputStream in = new FileInputStream(file); try { byte[] buf= new byte[1024]; for(int n;(n = in.read(buf)) != -1;) { out.write(buf,0,n); } } finally { try { in.close(); out.close(); } finally { file.delete(); file.deleteOnExit(); } }
这种代码解决了问题,但是还是不够好,我相信大部分人也不喜欢这种方式,虽然可以封装一个方法去做这个事情.后来用了一种更好的方式来解决这个问题,而且比较符合jfinal的设计哲学
方案2
自定义render由于jfinal已经有了FileRender,我们可以直接继承它,我们重写 render方法就好了,这种方法做到了代码重用,个人很喜欢,代码如下:
public class TempFileRender extends FileRender { private String fileName; private File file; public TempFileRender(String fileName) { super(fileName); this.fileName = fileName; } public TempFileRender(File file) { super(file); this.file = file; } @Override public void render() { try { super.render(); } finally { if(null != fileName) { file = new File(fileName); } if(null != file) { file.delete(); file.deleteOnExit(); } } } }
这样在controller中使用就只需要
render(new TempFileRender(file|fileName))了
打完收工
相关文章推荐
- 防止使用Struts2下载时取消出现异常,并实现支持下载完成后删除临时文件
- C#网站开发----在服务器上生成临时文件,下载到客户端,然后删除临时文件
- FTP 工具类. 可以完成对目录创建的创建、修改、删除,对文件的上传下载等操作
- Windows 7删除用户配置文件后使用临时配置文件
- Java实现FTP服务器的上传、下载、删除、查看文件列表
- SVN服务器部署并实现双机同步及禁止普通用户删除文件
- 利用WCF上传,下载,删除服务器文件
- Windows 7删除用户配置文件后使用临时配置文件
- php 下载完成后删除文件
- FTP 工具类. 可以完成对目录创建的创建、修改、删除,对文件的上传下载等操作
- 批量删除Maven jar包下载中断临时文件
- Windows 7删除用户配置文件后使用临时配置文件
- Windows 7删除用户配置文件后使用临时配置文件
- java向ftp服务器上传下载删除文件
- Java连接FTP服务器,并上传或下载以及删除ftp服务器中的文件
- win 7 删除了用户文件夹后出现的"你已使用临时配置文件登录"提示的解决方法
- 信息编辑,上传文件编辑、删除,用户个人资料修改程序完成 2004-08-21
- 【LoadRunner】同一用户同时通过FTP服务器下载文件问题
- 解决 服务器vsftpd安装完成后,用winscp不能上传和下载文件的问题
- java 通过sftp服务器上传下载删除文件