配色: 字号:
SpringMVC文件上传下载
2016-09-12 | 阅:  转:  |  分享 
  
SpringMVC文件上传下载
今天我们来讲讲springmvc中的文件上传和下载的几种方法。
首先附上文件目录->我们需要配置的我做了记号->

?
一、文件上传

首先为了方便后续的操作,以及精简代码,我们在Utils包下封装一个文件上传下载的帮助类:?Files_Helper_DG


1packageUtils;23importorg.springframework.web.multipart.MultipartFile;45importjavax.servlet.http.HttpServletRequest;6importjavax.servlet.http.HttpServletResponse;7importjava.io.;8importjava.text.SimpleDateFormat;9importjava.util.Date;10importjava.util.UUID;1112/13Author:qixiao14Time:2016年9月2日23:47:5115/16publicfinalclassFiles_Helper_DG{17/18私有构造方法,限制该类不能被实例化19/20privateFiles_Helper_DG(){21thrownewError("TheclassCannotbeinstance!");22}2324/25springmvcfilesUploadmethod(transferTomethod)26springmvc中的文件上传方法trasferTo的方式上传,参数为MultipartFile2728@paramrequestHttpServletRequest29@parammultipartFileMultipartFile(spring)30@paramfilePathfilePathexample"/files/Upload"31@return32/33publicstaticStringFilesUpload_transferTo_spring(HttpServletRequestrequest,MultipartFilemultipartFile,StringfilePath){34//getDatepath35StringDatePath=newSimpleDateFormat("yyyyMMdd").format(newDate());36//getserverpath(realpath)37StringsavePath=request.getSession().getServletContext().getRealPath(filePath)+File.separator+DatePath;38//ifdirnotexists,mkdir39System.out.println(savePath);40FilesaveDir=newFile(savePath);41if(!saveDir.exists()||!saveDir.isDirectory()){42//createdir43saveDir.mkdir();44}45if(multipartFile!=null){46//getfilessuffix47Stringsuffix=multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));48//useUUIDgetuuidstring49StringuuidName=UUID.randomUUID().toString()+suffix;//makenewfilename50//filePath+fileNamethecomplexfileName51StringfileName=savePath+File.separator+uuidName;52//returnrelativePath53StringrelativePath=filePath+File.separator+DatePath+File.separator+uuidName;54try{55//savefile56multipartFile.transferTo(newFile(fileName));57//returnrelativePath58returnrelativePath;59}catch(IOExceptione){60e.printStackTrace();61returnnull;62}63}else64returnnull;65}6667/68@paramrequestHttpServletRequest69@paramresponseHttpServletResponse70@paramfilePathexample"/filesOut/Download/mst.txt"71@return72/73publicstaticvoidFilesDownload_servlet(HttpServletRequestrequest,HttpServletResponseresponse,StringfilePath){74//getserverpath(realpath)75StringrealPath=request.getSession().getServletContext().getRealPath(filePath);76Filefile=newFile(realPath);77Stringfilenames=file.getName();78InputStreaminputStream;79try{80inputStream=newBufferedInputStream(newFileInputStream(file));81byte[]buffer=newbyte[inputStream.available()];82inputStream.read(buffer);83inputStream.close();84response.reset();85//先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名86response.addHeader("Content-Disposition","attachment;filename="+newString(filenames.replaceAll("","").getBytes("utf-8"),"iso8859-1"));87response.addHeader("Content-Length",""+file.length());88OutputStreamos=newBufferedOutputStream(response.getOutputStream());89response.setContentType("application/octet-stream");90os.write(buffer);//输出文件91os.flush();92os.close();93}catch(Exceptione){94e.printStackTrace();95}96}97}

?然后我们新建一个控制器类FileUploadController

首先我们先展示出全部的代码,然后我们进行分步说明--->
?FileUploadController
?方式一:采用fileUpload_multipartFile,file.transferTo来保存上传的文件

1/2方式一3采用fileUpload_multipartFile,file.transferTo来保存上传的文件4/5@RequestMapping(value="fileUpload_multipartFile")6@ResponseBody7publicStringfileUpload_multipartFile(HttpServletRequestrequest,@RequestParam("file_upload")MultipartFilemultipartFile){8//调用保存文件的帮助类进行保存文件,并返回文件的相对路径9StringfilePath=Files_Helper_DG.FilesUpload_transferTo_spring(request,multipartFile,"/filesOut/Upload");10return"{\"TFMark\":\"true\",\"Msg\":\"uploadsuccess!\",\"filePath\":\""+filePath+"\"}";11}

方式二:采用fileUpload_multipartRequestfile.transferTo来保存上传文件

1@RequestMapping(value="fileUpload_multipartRequest")2@ResponseBody3publicStringfileUpload_multipartRequest(HttpServletRequestrequest){4//将request转成MultipartHttpServletRequest5MultipartHttpServletRequestmultipartRequest=(MultipartHttpServletRequest)request;6//页面控件的文件流,对应页面控件inputfile_upload7MultipartFilemultipartFile=multipartRequest.getFile("file_upload");8//调用保存文件的帮助类进行保存文件,并返回文件的相对路径9StringfilePath=Files_Helper_DG.FilesUpload_transferTo_spring(request,multipartFile,"/filesOut/Upload");10return"{\"TFMark\":\"true\",\"Msg\":\"uploadsuccess!\",\"filePath\":\""+filePath+"\"}";11}

?方式三:采用CommonsMultipartResolverfile.transferTo来保存上传文件---自动扫描全部的input表单

1@RequestMapping(value="fileUpload_CommonsMultipartResolver")2@ResponseBody3publicStringfileUpload_CommonsMultipartResolver(HttpServletRequestrequest){4//将当前上下文初始化给CommonsMultipartResolver(多部分解析器)5CommonsMultipartResolvermultipartResolver=newCommonsMultipartResolver(request.getSession().getServletContext());6//检查form中是否有enctype="multipart/form-data"7if(multipartResolver.isMultipart(request)){8//将request变成多部分request9MultipartHttpServletRequestmultipartRequest=(MultipartHttpServletRequest)request;10//获取multiRequest中所有的文件名11Iteratoriter=multipartRequest.getFileNames();12while(iter.hasNext()){13//一次遍历所有文件14MultipartFilemultipartFile=multipartRequest.getFile(iter.next().toString());15//调用保存文件的帮助类进行保存文件,并返回文件的相对路径16StringfileName=Files_Helper_DG.FilesUpload_transferTo_spring(request,multipartFile,"/filesOut/Upload");17System.out.println(fileName);18}19}20return"uploadsuccess!";21}

方式四:通过流的方式上传文件(这种方法和servlet里面上传文件的方法类似,但本人这种方法存在上传文件损坏的问题,希望大神们能帮本人解决,感激不尽!~~~)

1@RequestMapping(value="fileUpload_stream")2@ResponseBody3publicStringfileUpload_stream(HttpServletRequestrequest){4//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全5StringsavePath=request.getSession().getServletContext().getRealPath("/filesOut/Upload");6Filefile=newFile(savePath);7//判断上传文件的保存目录是否存在8if(!file.exists()&&!file.isDirectory()){9//创建目录10file.mkdir();11}12try{13//使用Apache文件上传组件处理文件上传步骤:14//1、创建一个DiskFileItemFactory工厂15DiskFileItemFactoryfactory=newDiskFileItemFactory();16//2、创建一个文件上传解析器17ServletFileUploadupload=newServletFileUpload(factory);18//解决上传文件名的中文乱码19upload.setHeaderEncoding("UTF-8");20//3、判断提交上来的数据是否是上传表单的数据21if(!ServletFileUpload.isMultipartContent(request)){22//按照传统方式获取数据23return"isnotformuploaddata";24}25//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List集合,每一个FileItem对应一个Form表单的输入项26Listlist=upload.parseRequest(request);27System.out.println("start---------");28System.out.println(list);29for(FileItemitem:list){30System.out.println("begin----");31//如果fileitem中封装的是普通输入项的数据32if(item.isFormField()){33Stringname=item.getFieldName();34//解决普通输入项的数据的中文乱码问题35Stringvalue=item.getString("UTF-8");36//value=newString(value.getBytes("iso8859-1"),"UTF-8");37System.out.println(name+"="+value);38}else{//如果fileitem中封装的是上传文件39//得到上传的文件名称,40Stringfilename=item.getName();41System.out.println(filename);42if(filename==null||filename.trim().equals("")){43continue;44}45//注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt46//处理获取到的上传文件的文件名的路径部分,只保留文件名部分47Stringsuffix=item.getName().substring(item.getName().lastIndexOf("."));48//获取item中的上传文件的输入流49InputStreamin=item.getInputStream();50//创建一个文件输出流51FileOutputStreamout=newFileOutputStream(savePath+"/123"+suffix);52//创建一个缓冲区53bytebuffer[]=newbyte[1024];54//判断输入流中的数据是否已经读完的标识55intlen=0;56//循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据57while((len=in.read(buffer))>0){58//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath+"\\"+filename)当中59out.write(buffer,0,len);60}61//关闭输入流62in.close();63//关闭输出流64out.close();65//删除处理文件上传时生成的临时文件66item.delete();67}68}69return"uploadsuccess!";70}catch(Exceptione){71e.printStackTrace();72}73return"uploadfail";74}

多文件上传(其实是将上面的MultipartFile写成数组形式)

1@RequestMapping(value="fileUpload_spring_list")2@ResponseBody3publicStringfileUpload_spring_list(HttpServletRequestrequest,@RequestParam("file_upload")MultipartFile[]multipartFile){4//判断file数组不能为空并且长度大于05if(multipartFile!=null&&multipartFile.length>0){6//循环获取file数组中得文件7try{8for(inti=0;i
下面我们进行测试:
首先在webapp下新建文件夹目录/filesOut/Upload,并且新建一个/FileUpload/FileUpload.jsp

FileUpload.jsp代码如下

1<%@pagecontentType="text/html;charset=UTF-8"language="java"%>2<%3Stringpath=request.getContextPath();4StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";5%>678">9fileUpload101112

文件上传


1314

采用fileUpload_multipartFile,file.transferTo来保存上传的文件

1516171819
2021

采用fileUpload_www.wang027.commultipartRequestfile.transferTo来保存上传文件

2223242526
2728

采用CommonsMultipartResolverfile.transferTo来保存上传文件

2930313233
3435

使通过流的方式上传文件--存在上传后无法使用的问题

3637383940
4142

多文件上传采用MultipartFile[]multipartFile上传文件方法

43444546474849
5051

通过a标签的方式进行文件下载


52filesOut/Download/mst.txt">通过a标签下载文件mst.txt53
54

通过Response文件流的方式下载文件

55通过文件流的方式下载文件mst.txt565758

这里一定要记得在spring-servlet.xml里面配置访问静态路径方法->下面我附上spring-servlet.xml

1212131415161718192021222324252627282930313233343536373839

然后我们运行tomcat进入http://localhost:8080/Views/FileUpload/FileUpload.jsp
打开后,页面如下:

我们依次选择文件->

然后依次点击upload按钮,进行文件的上传->


?

?


可见,5种上传都已经执行成功!下面我们打开文件目录查看一下上传的文件->

细心的同志们会发现使用流上传的并没有成功,这种方式仍然存在bug待调试,有成功的记得联系我哦~
那么我们其他的方式执行已经都成功了!
?
?
二、文件下载

?在控制器类FileUploadController里面继续添加代码->
1@RequestMapping(value="fileDownload_servlet")2publicvoidfileDownload_servlet(HttpServletRequestrequest,HttpServletResponseresponse){3Files_Helper_DG.FilesDownload_servlet(request,response,"/filesOut/Download/mst.txt");4}
这里调用了帮助类?Files_Helper_DG.FilesDownload_servlet(request,response,"/filesOut/Download/mst.txt");
?然后我们进行测试->
前面我们新建的文件夹/filesOut/Download,在里面放一个文件mst.txt,代码访问的就是这个文件!

然后是我们FileUpload.jsp,前面已经拷贝过了这段代码->
1

通过a标签的方式进行文件下载


2filesOut/Download/mst.txt">通过a标签下载文件mst.txt3
4

通过Response文件流的方式下载文件

5通过文件流的方式下载文件mst.txt
首先是第一种直接访问文件目录,此方式有缺陷,暴露了项目文件结构,造成安全隐患!

点击便可下载!(如果浏览器可以读取文件,则会直接浏览器打开,我们可以右键->链接另存为选择路径保存)

然后我们点击第二种下载方式->实际项目中,我们应该优先选择第二种方式,提高了安全性!

从服务器直接下载到浏览器默认的保存文件目录!(本人在F:)

?
?到此,我们的springmvc文件上传下载已经实现!
献花(0)
+1
(本文系thedust79首藏)