在web下文件上传和下载是比较常见的,在这里整理下。
首先是文件上传,本文采用的是struts2的框架,所有的过滤工作都由它来完成,上传的前端比较简单:
<span class="wenbenming" style="float:left;margin-left:100px;margin-top:10px;"> 文件上传:</span>
<input type="text" id="tx" style=" 300px;height:30px;font-size:17px;" lang="1" /> <input size="30" type="file" name="myFile" onchange="tx.value=this.value" style="290px; margin-left:-300px; filter:alpha(opacity=0); opacity:0;" />
这里只是列出主要元素 ,具体布局还要靠大家自己把握,首先介绍下这里的"file" 样式为隐藏的,原因就是file上传后不会保存具体的文件名,而是以临时文件.temp的形式存到服务器上,上传工作完成后便会被服务器删除,所以为了保存上传文件的名字增加"text"属性框。
private IFileTableService ifileTableService; private FileTable ftobj; private List<FileTable> ltlist; private String fileName; // myFile属性用来封装上传的文件 private File myFile; // myFileContentType属性用来封装上传文件的类型 private String myFileContentType; // myFileFileName属性用来封装上传文件的文件名 private String myFileFileName; private String fname; private FileInputStream fstream; public String addfile() throws Exception{ //获得servlet容器,目的是为了得到工程的路径,这里得到的应该是class文件所在的路径
ServletContext sc = ServletActionContext.getServletContext(); //通过getRealPath方法获得上传文件所在的路径,这里是放在“fupload”文件夹下
String realPath = sc.getRealPath("/fupload");
//为了防止文件重复,这里我们通过获取系统时间的方法获得一个名字
long longtime = (new Date()).getTime(); //上传的文件名+从系统获得的文件名即可保证文件不会重复
String newfilePath = realPath+"//"+longtime+myFileFileName; //创建文件对象
File dest = new File(newfilePath); //使用FileUtil工具类将上传的文件拷贝到fupload文件夹下
FileUtil.copy(myFile, dest);//文件保存在upload目录下 //以下的为保存到数据库中的相关描述数据
ftobj.setFname(myFileFileName); ftobj.setFurl(newfilePath); ifileTableService.addfile(ftobj); return SUCCESS; }
上面的代码为上传文件的后台,注释比较详细,在此不多做解释,之后再给出struts2的相关配置代码:
<package name="fileManagement" extends="struts-default"> <action name="listtable_*" class="com.zxpg.action.FileTableAction" method="{1}"> <result name="success">/fileupload.jsp</result> <result name="input">/xiazai.jsp</result> <result name="down" type="stream"> <param name="inputName">fstream</param> <!-- 告诉浏览器,返回的流以另存为窗口形式对待, 窗口显示文件名为action的fname值 --> <param name="contentDisposition"> attachment;filename=${fname} </param> </result> <interceptor-ref name="fileUpload"> <param name="allowedTypes">application/msword,text/plain</param> <param name="maximumSize">10240000</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package>
上传与下载文件的url都通过通配符的方式访问,对于下载文件项的返回需要增加一个参数,表明返回的形式是以流的形式对待,我们这里请看下上传的拦截器,就是最后的几行,这里明确的限制了上传文件的类型,只允许nsword(word文档类型),text/plain(txt文本类型),最后限制了上传文件的大小(不得大于10M),通过strut2简单配置,省去了自己写过滤的工作,也是十分方便。
文件下载的工作不给出前端界面,因为这里只是把上传的文件通过数据库保存的描述记录列举到浏览器上,之后下载用户点击相应的文件会访问到下载文件的后台,下面给出后台处理的代码:
public String downLoadFile(){ //检查是否有权限 // return "noright";//可以定位到提示页面去 // SmartUpload mySmartUpload =new SmartUpload(); //定位fname资源, ServletContext sc = ServletActionContext.getServletContext(); String realPath = sc.getRealPath("/fupload"); String filePath = ftobj.getFurl(); try{ // 给fstream赋值 // fname = new String(ftobj.getFname().getBytes("ISO-8859-1"),"utf-8"); fname = new String(ftobj.getFname().getBytes("utf-8"),"ISO-8859-1"); // filePath=new String(filePath.getBytes("ISO-8859-1"),"utf-8"); fstream = new FileInputStream(filePath);
return "down";//调用stream result输出 }catch(Exception ex){ ex.printStackTrace(); return "error"; } }
可以看到最后我们得到fstream这个相关文件的流对象,struts2的配置我在上面已经提到,对于下载这个请求的返回我们把它设置为“以流的形式对待”,也就是这个文件会以流的形式返回给前端下载,这样的好处是无论是什么样的文件都可以提供一个下载项,相比直接在文件列表上附加这个文件所在地的超链接,无论是安全性还是兼容性都有优势。