首页 > 代码库 > SpringMVC文件上传下载
SpringMVC文件上传下载
在Spring MVC的基础框架搭建起来后,我们测试了spring mvc中的返回值类型,如果你还没有搭建好springmvc的架构请参考博文->http://www.cnblogs.com/qixiaoyizhan/p/5819392.html
今天我们来讲讲spring mvc中的文件上传和下载的几种方法。
首先附上文件目录->我们需要配置的我做了记号->
一、文件上传
首先为了方便后续的操作,以及精简代码,我们在Utils包下封装一个文件上传下载的帮助类: Files_Helper_DG
Files_Helper_DG 代码
package Utils; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; /** * Author:qixiao * Time:2016-9-2 23:47:51 */ public final class Files_Utils_DG { /** * private constructor method that make class can not be instantiation */ private Files_Utils_DG() { throw new Error("The class Cannot be instance !"); } /** * spring mvc files Upload method (transferTo method) * MultipartFile use TransferTo method upload * * @param request HttpServletRequest * @param multipartFile MultipartFile(spring) * @param filePath filePath example "/files/Upload" * @return */ public static String FilesUpload_transferTo_spring(HttpServletRequest request, MultipartFile multipartFile, String filePath) { if (multipartFile != null) { //get files suffix String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")); //filePath+fileName the complex file Name String absolutePath = getAndSetAbsolutePath(request, filePath, suffix); //return relative Path String relativePath = getRelativePath(filePath, suffix); try { //save file multipartFile.transferTo(new File(absolutePath)); //return relative Path return relativePath; } catch (IOException e) { e.printStackTrace(); return null; } } else return null; } /** * user stream type save files * @param request HttpServletRequest * @param multipartFile MultipartFile support CommonsMultipartFile file * @param filePath filePath example "/files/Upload" * @return */ public static String FilesUpload_stream(HttpServletRequest request,MultipartFile multipartFile,String filePath) { if (multipartFile != null) { //get files suffix String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")); //filePath+fileName the complex file Name String absolutePath = getAndSetAbsolutePath(request, filePath, suffix); //return relative Path String relativePath = getRelativePath(filePath, suffix); try{ InputStream inputStream = multipartFile.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream(absolutePath); byte buffer[] = new byte[4096]; //create a buffer long fileSize = multipartFile.getSize(); if(fileSize<=buffer.length){//if fileSize < buffer buffer = new byte[(int)fileSize]; } int line =0; while((line = inputStream.read(buffer)) >0 ) { fileOutputStream.write(buffer,0,line); } fileOutputStream.close(); inputStream.close(); return relativePath; }catch (Exception e){ e.printStackTrace(); } } else return null; return null; } /** * @param request HttpServletRequest * @param response HttpServletResponse * @param filePath example "/filesOut/Download/mst.txt" * @return */ public static void FilesDownload_stream(HttpServletRequest request, HttpServletResponse response, String filePath) { //get server path (real path) String realPath = request.getSession().getServletContext().getRealPath(filePath); File file = new File(realPath); String filenames = file.getName(); InputStream inputStream; try { inputStream = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[inputStream.available()]; inputStream.read(buffer); inputStream.close(); response.reset(); // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名 response.addHeader("Content-Disposition", "attachment;filename=" + new String(filenames.replaceAll(" ", "").getBytes("utf-8"), "iso8859-1")); response.addHeader("Content-Length", "" + file.length()); OutputStream os = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); os.write(buffer);// 输出文件 os.flush(); os.close(); } catch (Exception e) { e.printStackTrace(); } } //------------------------------------------------------------------------------- //return server absolute path(real path) public static String getServerPath(HttpServletRequest request, String filePath) { return request.getSession().getServletContext().getRealPath(filePath); } //return a dir that named date of today ; example:20160912 public static String getDataPath() { return new SimpleDateFormat("yyyyMMdd").format(new Date()); } //check if the path has exist if not create it public static void checkDir(String savePath) { File dir = new File(savePath); if (!dir.exists() || !dir.isDirectory()) { dir.mkdir(); } } //return an UUID Name parameter (suffix cover ‘.‘) example: ".jpg"、".txt" public static String getUUIDName(String suffix) { return UUID.randomUUID().toString() + suffix;// make new file name } //return server absolute path(real path) the style is “server absolute path/DataPath/UUIDName”filePath example "/files/Upload" public static String getAndSetAbsolutePath(HttpServletRequest request, String filePath, String suffix) { String savePath = getServerPath(request, filePath) + File.separator + getDataPath() + File.separator;//example:F:/qixiao/files/Upload/20160912/ checkDir(savePath);//check if the path has exist if not create it return savePath + getUUIDName(suffix); } //get the relative path of files style is “/filePath/DataPath/UUIDName”filePath example "/files/Upload" public static String getRelativePath(String filePath, String suffix) { return filePath + File.separator + getDataPath() + File.separator + getUUIDName(suffix);//example:/files/Upload/20160912/ } }
然后我们新建一个控制器类 FileUploadController
首先我们先展示出全部的代码,然后我们进行分步说明--->
package HelloSpringMVC.controller; import Utils.Files_Utils_DG; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Iterator; /** * Created by qixiao on 2016/8/30. */ @Controller @RequestMapping(value = "http://www.mamicode.com/FileUpload/*") public class FileUploadController { /* * 方式一 * 采用 fileUpload_multipartFile , file.transferTo 来保存上传的文件 */ @RequestMapping(value = "http://www.mamicode.com/fileUpload_multipartFile") @ResponseBody public String fileUpload_multipartFile(HttpServletRequest request, @RequestParam("file_upload") MultipartFile multipartFile) { //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String filePath = Files_Utils_DG.FilesUpload_transferTo_spring(request, multipartFile, "/files/upload"); return "{‘TFMark‘:‘true‘,‘Msg‘:‘upload success !‘,‘filePath‘:‘" + filePath + "‘}"; } /* * 方式二 * 采用 fileUpload_multipartRequest file.transferTo 来保存上传文件 * 参数不写 MultipartFile multipartFile 在request请求里面直接转成multipartRequest,从multipartRequest中获取到文件流 */ @RequestMapping(value = "http://www.mamicode.com/fileUpload_multipartRequest") @ResponseBody public String fileUpload_multipartRequest(HttpServletRequest request) { //将request转成MultipartHttpServletRequest MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; //页面控件的文件流,对应页面控件 input file_upload MultipartFile multipartFile = multipartRequest.getFile("file_upload"); //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String filePath = Files_Utils_DG.FilesUpload_transferTo_spring(request, multipartFile, "/files/upload"); return "{‘TFMark‘:‘true‘,‘Msg‘:‘upload success !‘,‘filePath‘:‘" + filePath + "‘}"; } /* * 方式三 * 采用 CommonsMultipartResolver file.transferTo 来保存上传文件 * 自动扫描全部的input表单 */ @RequestMapping(value = "http://www.mamicode.com/fileUpload_CommonsMultipartResolver") @ResponseBody public String fileUpload_CommonsMultipartResolver(HttpServletRequest request) { //将当前上下文初始化给 CommonsMultipartResolver (多部分解析器) CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext()); //检查form中是否有enctype="multipart/form-data" if (multipartResolver.isMultipart(request)) { //将request变成多部分request MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; //获取multiRequest 中所有的文件名 Iterator iter = multipartRequest.getFileNames(); while (iter.hasNext()) { //一次遍历所有文件 MultipartFile multipartFile = multipartRequest.getFile(iter.next().toString()); //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String fileName = Files_Utils_DG.FilesUpload_transferTo_spring(request, multipartFile, "/files/upload"); System.out.println(fileName); } } return "upload success ! "; } /* * 方式四 * 通过流的方式上传文件 */ @RequestMapping("fileUpload_stream") @ResponseBody public String upFile(HttpServletRequest request, @RequestParam("file_upload") MultipartFile multipartFile){ String filePath= Files_Utils_DG.FilesUpload_stream(request,multipartFile,"/files/upload"); return "{‘TFMark‘:‘true‘,‘Msg‘:‘upload success !‘,‘filePath‘:‘" + filePath + "‘}"; } /* * 方式五 * 采用 fileUpload_ajax , file.transferTo 来保存上传的文件 异步 */ @RequestMapping(value = "http://www.mamicode.com/fileUpload_ajax",method = RequestMethod.POST,produces = {"application/json;charset=UTF-8"}) @ResponseBody public String fileUpload_ajax(HttpServletRequest request, @RequestParam("file_AjaxFile") MultipartFile multipartFile) { //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String filePath = Files_Utils_DG.FilesUpload_transferTo_spring(request, multipartFile, "/files/upload"); return "{‘TFMark‘:‘true‘,‘Msg‘:‘upload success !‘,‘filePath‘:‘" + filePath + "‘}"; } /* * 多文件上传 * 采用 MultipartFile[] multipartFile 上传文件方法 */ @RequestMapping(value = "http://www.mamicode.com/fileUpload_spring_list") @ResponseBody public String fileUpload_spring_list(HttpServletRequest request, @RequestParam("file_upload") MultipartFile[] multipartFile) { //判断file数组不能为空并且长度大于0 if (multipartFile != null && multipartFile.length > 0) { //循环获取file数组中得文件 try { for (int i = 0; i < multipartFile.length; i++) { MultipartFile file = multipartFile[i]; //保存文件 String fileName = Files_Utils_DG.FilesUpload_transferTo_spring(request, file, "/files/upload"); System.out.println(fileName); } return "{‘TFMark‘:‘true‘,‘Msg‘:‘upload success !‘}"; } catch (Exception ee) { return "{‘TFMark‘:‘false‘,‘Msg‘:‘参数传递有误!‘}"; } } return "{‘TFMark‘:‘false‘,‘Msg‘:‘参数传递有误!‘}"; } /** * 文件下载 * * @param response */ @RequestMapping(value = "http://www.mamicode.com/fileDownload_servlet") public void fileDownload_servlet(HttpServletRequest request, HttpServletResponse response) { Files_Utils_DG.FilesDownload_stream(request,response,"/files/download/mst.txt"); } }
方式一:采用 fileUpload_multipartFile , file.transferTo 来保存上传的文件
/* * 方式一 * 采用 fileUpload_multipartFile , file.transferTo 来保存上传的文件 */ @RequestMapping(value = "http://www.mamicode.com/fileUpload_multipartFile") @ResponseBody public String fileUpload_multipartFile(HttpServletRequest request, @RequestParam("file_upload") MultipartFile multipartFile) { //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String filePath = Files_Helper_DG.FilesUpload_transferTo_spring(request, multipartFile, "/filesOut/Upload"); return "{\"TFMark\":\"true\",\"Msg\":\"upload success !\",\"filePath\":\"" + filePath + "\"}"; }
方式二:采用 fileUpload_multipartRequest file.transferTo 来保存上传文件
@RequestMapping(value = "http://www.mamicode.com/fileUpload_multipartRequest") @ResponseBody public String fileUpload_multipartRequest(HttpServletRequest request) { //将request转成MultipartHttpServletRequest MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; //页面控件的文件流,对应页面控件 input file_upload MultipartFile multipartFile = multipartRequest.getFile("file_upload"); //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String filePath = Files_Helper_DG.FilesUpload_transferTo_spring(request, multipartFile, "/filesOut/Upload"); return "{\"TFMark\":\"true\",\"Msg\":\"upload success !\",\"filePath\":\"" + filePath + "\"}"; }
方式三:采用 CommonsMultipartResolver file.transferTo 来保存上传文件---自动扫描全部的input表单
@RequestMapping(value = "http://www.mamicode.com/fileUpload_CommonsMultipartResolver") @ResponseBody public String fileUpload_CommonsMultipartResolver(HttpServletRequest request) { //将当前上下文初始化给 CommonsMultipartResolver (多部分解析器) CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext()); //检查form中是否有enctype="multipart/form-data" if (multipartResolver.isMultipart(request)) { //将request变成多部分request MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; //获取multiRequest 中所有的文件名 Iterator iter = multipartRequest.getFileNames(); while (iter.hasNext()) { //一次遍历所有文件 MultipartFile multipartFile = multipartRequest.getFile(iter.next().toString()); //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String fileName = Files_Helper_DG.FilesUpload_transferTo_spring(request, multipartFile, "/filesOut/Upload"); System.out.println(fileName); } } return "upload success ! "; }
方式四:通过流的方式上传文件
1 @RequestMapping("fileUpload_stream") 2 @ResponseBody 3 public String upFile(HttpServletRequest request, @RequestParam("file_upload") MultipartFile multipartFile){ 4 String filePath=Files_Helper_DG.FilesUpload_stream(request,multipartFile,"/filesOut/Upload"); 5 return "{\"TFMark\":\"true\",\"Msg\":\"upload success !\",\"filePath\":\"" + filePath + "\"}"; 6 }
方式五:采用ajaxFileUpload.js插件与异步上传的方式上传文件
@RequestMapping(value = "http://www.mamicode.com/fileUpload_ajax",method = RequestMethod.POST,produces = {"application/json;charset=UTF-8"}) @ResponseBody public String fileUpload_ajax(HttpServletRequest request, @RequestParam("file_AjaxFile") MultipartFile multipartFile) { //调用保存文件的帮助类进行保存文件,并返回文件的相对路径 String filePath = Files_Utils_DG.FilesUpload_transferTo_spring(request, multipartFile, "/files/upload"); return "{‘TFMark‘:‘true‘,‘Msg‘:‘upload success !‘,‘filePath‘:‘" + filePath + "‘}"; }
上述方法需要 ajaxfileupload.js 插件的支持,该插件
多文件上传(其实是将上面的 MultipartFile 写成数组形式)
@RequestMapping(value = "http://www.mamicode.com/fileUpload_spring_list") @ResponseBody public String fileUpload_spring_list(HttpServletRequest request, @RequestParam("file_upload") MultipartFile[] multipartFile) { //判断file数组不能为空并且长度大于0 if (multipartFile != null && multipartFile.length > 0) { //循环获取file数组中得文件 try { for (int i = 0; i < multipartFile.length; i++) { MultipartFile file = multipartFile[i]; //保存文件 String fileName = Files_Helper_DG.FilesUpload_transferTo_spring(request, file, "/filesOut/Upload"); System.out.println(fileName); } return "{\"TFMark\":\"true\",\"Msg\":\"upload success !\"}"; } catch (Exception ee) { return "{\"TFMark\":\"false\",\"Msg\":\"参数传递有误!\"}"; } } return "{\"TFMark\":\"false\",\"Msg\":\"参数传递有误!\"}"; }
下面我们进行测试:
首先在webapp下新建文件夹目录/files/download,并且新建一个/Views/FileUpload/FileUpload.jsp
注意文件目录结构以及目录层次!!!
FileUpload.jsp代码如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <html> <head> <base href="http://www.mamicode.com/"> <title>fileUpload</title> <script src="http://www.mamicode.com/scripts/jquery-1.11.1.js"></script> <script src="http://www.mamicode.com/scripts/ajaxfileupload.js"></script> </head> <body> <h3>文件上传</h3><br> <h3>采用 fileUpload_multipartFile , file.transferTo 来保存上传的文件</h3> <form name="form1" action="/FileUpload/fileUpload_multipartFile" method="post" enctype="multipart/form-data"> <input type="file" name="file_upload"> <input type="submit" value="http://www.mamicode.com/upload"/> </form> <hr> <h3>采用 fileUpload_multipartRequest file.transferTo 来保存上传文件</h3> <form name="form2" action="/FileUpload/fileUpload_multipartRequest" method="post" enctype="multipart/form-data"> <input type="file" name="file_upload"> <input type="submit" value="http://www.mamicode.com/upload"/> </form> <hr> <h3>采用 CommonsMultipartResolver file.transferTo 来保存上传文件</h3> <form name="form3" action="/FileUpload/fileUpload_CommonsMultipartResolver" method="post" enctype="multipart/form-data"> <input type="file" name="file_upload"> <input type="submit" value="http://www.mamicode.com/upload"/> </form> <hr> <h3>通过流的方式上传文件</h3> <form name="form4" action="/FileUpload/fileUpload_stream" method="post" enctype="multipart/form-data"> <input type="file" name="file_upload"> <input type="submit" value="http://www.mamicode.com/upload"/> </form> <hr> <h3>通过ajax插件 ajaxfileupload.js 来异步上传文件</h3> <form name="form5" action="/" method="post" enctype="multipart/form-data"> <input type="file" id="file_AjaxFile" name="file_AjaxFile"> <input type="button" value="http://www.mamicode.com/upload" onclick="fileUploadAjax()"/><span id="sp_AjaxFile"></span><br><br> 上传进度:<span id="sp_fileUploadProgress">0%</span> </form> <script type="text/javascript"> function fileUploadAjax() { if ($("#file_AjaxFile").val().length > 0) { progressInterval=setInterval(getProgress,500); $.ajaxFileUpload({ url: ‘/FileUpload/fileUpload_ajax‘, //用于文件上传的服务器端请求地址 type: "post", secureuri: false, //一般设置为false fileElementId: ‘file_AjaxFile‘, //文件上传空间的id属性 <input type="file" id="file1" name="file" /> dataType: ‘application/json‘, //返回值类型 一般设置为json success: function (data) //服务器成功响应处理函数 { var jsonObject = eval(‘(‘ + data + ‘)‘); $("#sp_AjaxFile").html(" Upload Success ! filePath:" + jsonObject.filePath); }, error: function (data, status, e)//服务器响应失败处理函数 { alert(e); } });//end ajaxfile } else { alert("请选择文件!"); } } var progressInterval = null; var i=0; var getProgress=function (){ $.get("/FileUpload/fileUploadprogress", {}, function (data) { $("#sp_fileUploadProgress").html(i+++data); if(data=http://www.mamicode.com/=100||i==100)"form5" action="/FileUpload/fileUpload_spring_list" method="post" enctype="multipart/form-data"> <input type="file" name="file_upload"> <input type="file" name="file_upload"> <input type="file" name="file_upload"> <input type="submit" value="http://www.mamicode.com/upload"/> </form> <hr> <h3>通过 a 标签的方式进行文件下载</h3><br> <a href="http://www.mamicode.com/filesOut/Download/mst.txt">通过 a 标签下载文件 mst.txt</a> <hr> <h3>通过 Response 文件流的方式下载文件</h3> <a href="http://www.mamicode.com/FileUpload/fileDownload_servlet">通过 文件流 的方式下载文件 mst.txt</a> </body> </html>
这里一定要记得在spring-servlet.xml里面配置访问静态路径方法->下面我附上spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> <!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射--> <mvc:annotation-driven > </mvc:annotation-driven> <!-- 启动包扫描功能,以便注册带有@Controller、@service、@repository、@Component等注解的类成为spring的bean --> <context:component-scan base-package="HelloSpringMVC.controller" /> <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="http://www.mamicode.com/org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="http://www.mamicode.com/"/> <!-- 前缀 --> <property name="suffix" value="http://www.mamicode.com/.jsp"/> <!-- 后缀 --> </bean> <!-- 访问静态文件(jpg,js,css)的方法 --> <mvc:resources location="/files/" mapping="/files/**" /> <mvc:resources location="/scripts/" mapping="/scripts/**" /> <mvc:resources location="/styles/" mapping="/styles/**" /> <mvc:resources location="/Views/" mapping="/Views/**" /> <!-- 多部分文件上传 需配置MultipartResolver处理器--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="http://www.mamicode.com/104857600" /> <property name="maxInMemorySize" value="http://www.mamicode.com/4096" /> <property name="defaultEncoding" value="http://www.mamicode.com/UTF-8"></property> </bean> <!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException --> <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 --> <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 --> <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop> </props> </property> </bean> </beans>
然后我们运行tomcat进入http://localhost:8080/Views/FileUpload/FileUpload.jsp
打开后,页面如下:
我们依次选择文件->
共八个文件!
然后依次点击upload按钮,进行文件的上传->
可见,六种上传都已经执行成功!下面我们打开文件目录查看一下上传的文件->
一共八个文件!证明所有文件都上传成功了!
二、文件下载
在控制器类 FileUploadController里面继续添加代码->
1 @RequestMapping(value = "http://www.mamicode.com/fileDownload_servlet") 2 public void fileDownload_servlet(HttpServletRequest request, HttpServletResponse response) { 3 Files_Helper_DG.FilesDownload_servlet(request,response,"/filesOut/Download/mst.txt"); 4 }
这里调用了帮助类 Files_Helper_DG.FilesDownload_servlet(request,response,"/filesOut/Download/mst.txt");
然后我们进行测试->
前面我们新建的文件夹/files/download,在里面放一个文件mst.txt,代码访问的就是这个文件!
然后是我们FileUpload.jsp,前面已经拷贝过了这段代码->
1 <h3>通过 a 标签的方式进行文件下载</h3><br>
2 <a href="<%=basePath%>filesOut/Download/mst.txt">通过 a 标签下载文件 mst.txt</a>
3 <hr>
4 <h3>通过 Response 文件流的方式下载文件</h3>
5 <a href="/FileUpload/fileDownload_servlet">通过 文件流 的方式下载文件 mst.txt</a>
首先是第一种直接访问文件目录,此方式有缺陷,暴露了项目文件结构,造成安全隐患!
点击便可下载!(如果浏览器可以读取文件,则会直接浏览器打开,我们可以右键->链接另存为选择路径保存)
然后我们点击第二种下载方式->实际项目中,我们应该优先选择第二种方式,提高了安全性!
从服务器直接下载到浏览器默认的保存文件目录!(本人在F:)
到此,我们的 spring mvc 文件上传下载已经实现!
SpringMVC文件上传下载