Spring MVC 文件上传 & 文件下载
索引:
参看代码 GitHub:
一、要点讲解
1.引入文件上传下载的类库
commons-fileupload
commons-io
2.配置 MultipartResolver 组件(bean)
@Bean public MultipartResolver multipartResolver() : 该组件用来 解析 http multipart 类型的请求体
3.配置静态文件的请求
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) :
该方法中注册请求资源路径,以便 href 链接中静态资源的请求链接与下载。
registry.addResourceHandler("/files/**").addResourceLocations("classpath:/files/");
4.添加页面快捷转向,这样就不用写没有逻辑仅做页面转向的 Controller 了
@Override public void addViewControllers(ViewControllerRegistry registry):
registry.addViewController("/upload").setViewName("fileupload/upload");
5.前台表单中的设置
enctype="multipart/form-data" :在 form 表单中必须指定为 multipart
fileElementId:'file_AjaxFile' :在 ajax 中要指定 <input type="file"> 的 id
6.后台中接收设置
@RequestParam("file_upload") MultipartFile multipartFile : 在方法参数中这样指定后,就可以从请求体中读取上传的文件及文件信息了
7.其它详细细节可具体参看代码,及代码中的解释
... ...
二、详细使用及代码
1.pom.xml
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <parent> 4 <artifactId>solution</artifactId> 5 <groupId>lm.solution</groupId> 6 <version>1.0-SNAPSHOT</version> 7 </parent> 8 <modelVersion>4.0.0</modelVersion> 9 <groupId>lm.solution</groupId> 10 <artifactId>web</artifactId> 11 <packaging>war</packaging> 12 <version>1.0-SNAPSHOT</version> 13 <name>web Maven Webapp</name> 14 <url>http://maven.apache.org</url> 15 <dependencies> 16 <!--Module--> 17 <dependency> 18 <groupId>lm.solution</groupId> 19 <artifactId>service</artifactId> 20 <version>1.0-SNAPSHOT</version> 21 </dependency> 22 <dependency> 23 <groupId>lm.solution</groupId> 24 <artifactId>common</artifactId> 25 <version>1.0-SNAPSHOT</version> 26 </dependency> 27 28 <!--Libary--> 29 <!--spring mvc--> 30 <dependency> 31 <groupId>org.springframework</groupId> 32 <artifactId>spring-webmvc</artifactId> 33 </dependency> 34 <!--cglib--> 35 <dependency> 36 <groupId>cglib</groupId> 37 <artifactId>cglib</artifactId> 38 </dependency> 39 <!-- mybatis核心包 --> 40 <dependency> 41 <groupId>org.mybatis</groupId> 42 <artifactId>mybatis</artifactId> 43 </dependency> 44 <!--mybatis spring 插件 --> 45 <dependency> 46 <groupId>org.mybatis</groupId> 47 <artifactId>mybatis-spring</artifactId> 48 </dependency> 49 <!-- Mysql数据库驱动包 --> 50 <dependency> 51 <groupId>mysql</groupId> 52 <artifactId>mysql-connector-java</artifactId> 53 </dependency> 54 <!-- connection pool --> 55 <dependency> 56 <groupId>com.alibaba</groupId> 57 <artifactId>druid</artifactId> 58 <!--<scope>runtime</scope>--> 59 </dependency> 60 <!--servlet--> 61 <dependency> 62 <groupId>javax.servlet</groupId> 63 <artifactId>javax.servlet-api</artifactId> 64 <scope>provided</scope> 65 </dependency> 66 <dependency> 67 <groupId>javax.servlet.jsp</groupId> 68 <artifactId>jsp-api</artifactId> 69 <scope>provided</scope> 70 </dependency> 71 <dependency> 72 <groupId>javax.servlet</groupId> 73 <artifactId>jstl</artifactId> 74 </dependency> 75 <!-- 映入JSON lib --> 76 <dependency> 77 <groupId>net.sf.json-lib</groupId> 78 <artifactId>json-lib</artifactId> 79 <classifier>jdk15</classifier> 80 </dependency> 81 <!-- 用dom4j解析xml文件 --> 82 <dependency> 83 <groupId>dom4j</groupId> 84 <artifactId>dom4j</artifactId> 85 </dependency> 86 <!-- ehcache --> 87 <dependency> 88 <groupId>net.sf.ehcache</groupId> 89 <artifactId>ehcache-core</artifactId> 90 </dependency> 91 <dependency> 92 <groupId>net.sf.ehcache</groupId> 93 <artifactId>ehcache-web</artifactId> 94 </dependency> 95 <!-- 上传组件包 --> 96 <dependency> 97 <groupId>commons-fileupload</groupId> 98 <artifactId>commons-fileupload</artifactId> 99 </dependency> 100 <dependency> 101 <groupId>commons-io</groupId> 102 <artifactId>commons-io</artifactId> 103 </dependency> 104 <!-- common others --> 105 <dependency> 106 <groupId>commons-codec</groupId> 107 <artifactId>commons-codec</artifactId> 108 </dependency> 109 <dependency> 110 <groupId>org.apache.commons</groupId> 111 <artifactId>commons-collections4</artifactId> 112 </dependency> 113 <dependency> 114 <groupId>org.apache.commons</groupId> 115 <artifactId>commons-lang3</artifactId> 116 </dependency> 117 <!-- commons-beanutils --> 118 <dependency> 119 <groupId>commons-beanutils</groupId> 120 <artifactId>commons-beanutils</artifactId> 121 <exclusions> 122 <exclusion> 123 <groupId>commons-logging</groupId> 124 <artifactId>commons-logging</artifactId> 125 </exclusion> 126 </exclusions> 127 </dependency> 128 <!-- freemarker --> 129 <dependency> 130 <groupId>org.freemarker</groupId> 131 <artifactId>freemarker</artifactId> 132 </dependency> 133 <!-- org.apache.httpcomponents --> 134 <dependency> 135 <groupId>org.apache.httpcomponents</groupId> 136 <artifactId>httpcore</artifactId> 137 </dependency> 138 <dependency> 139 <groupId>org.apache.httpcomponents</groupId> 140 <artifactId>httpclient</artifactId> 141 </dependency> 142 <!-- redis.clients/jedis --> 143 <dependency> 144 <groupId>redis.clients</groupId> 145 <artifactId>jedis</artifactId> 146 </dependency> 147 <!-- com.rabbitmq/amqp-client --> 148 <dependency> 149 <groupId>com.rabbitmq</groupId> 150 <artifactId>amqp-client</artifactId> 151 </dependency> 152 <!-- com.alibaba/fastjson --> 153 <dependency> 154 <groupId>com.alibaba</groupId> 155 <artifactId>fastjson</artifactId> 156 </dependency> 157 </dependencies> 158 <build> 159 <finalName>web</finalName> 160 161 <plugins> 162 <plugin> 163 <groupId>org.apache.tomcat.maven</groupId> 164 <artifactId>tomcat8-maven-plugin</artifactId> 165 </plugin> 166 </plugins> 167 </build> 168 </project>
2.WebConfig.java
1 package lm.solution.web.config.configs; 2 3 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; 4 import lm.solution.common.web.messageconverter.CustomMessageConverter; 5 import lm.solution.web.config.beans.TimerInterceptor; 6 import org.springframework.context.annotation.Bean; 7 import org.springframework.context.annotation.ComponentScan; 8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.http.MediaType; 10 import org.springframework.http.converter.HttpMessageConverter; 11 import org.springframework.web.multipart.MultipartResolver; 12 import org.springframework.web.multipart.commons.CommonsMultipartResolver; 13 import org.springframework.web.servlet.config.annotation.*; 14 import org.springframework.web.servlet.view.InternalResourceViewResolver; 15 import org.springframework.web.servlet.view.JstlView; 16 17 import java.util.ArrayList; 18 import java.util.List; 19 20 @Configuration 21 /** 22 * @EnableWebMvc 注解会开启一些默认配置,如:ViewResolver MessageConverter 等, 23 * 若无此注解,重写 WebMvcConfigurerAdapter 方法无效 24 * */ 25 @EnableWebMvc 26 @ComponentScan(value = { 27 "lm.solution.web", 28 "lm.solution.service.mysql", 29 "lm.solution.service.webtest" 30 }) 31 /** 32 * 继承 WebMvcConfigurerAdapter 类,重写其方法可对 spring mvc 进行配置 33 * */ 34 public class WebConfig extends WebMvcConfigurerAdapter { 35 36 // 重写 addViewControllers 简化页面快捷转向,这样就可以不用配置 Controller 了 37 @Override 38 public void addViewControllers(ViewControllerRegistry registry) { 39 40 registry.addViewController("/").setViewName("index"); 41 registry.addViewController("/error").setViewName("error/error"); 42 registry.addViewController("/excel").setViewName("excel/excel"); 43 // 文件上传下载 44 registry.addViewController("/upload").setViewName("fileupload/upload"); 45 registry.addViewController("/ImageValidateCodeLogin").setViewName("login/imageValidateCodeLogin"); 46 registry.addViewController("/restfulapi").setViewName("restful/user"); 47 registry.addViewController("/jaxwsri").setViewName("jaxwsri/wsri"); 48 registry.addViewController("/redis").setViewName("redis/jedis"); 49 registry.addViewController("/mybatisPage").setViewName("db/mybatis"); 50 registry.addViewController("/messageconverter").setViewName("httpmessageconverter/customconverter"); 51 registry.addViewController("/sse").setViewName("serverpushmessage/sse"); 52 53 } 54 55 // 配置JSP视图解析器 56 @Bean 57 public InternalResourceViewResolver viewResolver() { 58 InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 59 /** 60 * views 在 /resources/ 下 61 * */ 62 // 前缀 63 viewResolver.setPrefix("/WEB-INF/classes/views/"); 64 // 后缀 65 viewResolver.setSuffix(".jsp"); 66 viewResolver.setViewClass(JstlView.class); 67 viewResolver.setContentType("text/html"); 68 // 可以在JSP页面中通过${}访问beans 69 viewResolver.setExposeContextBeansAsAttributes(true); 70 return viewResolver; 71 } 72 73 // 配置springMVC处理上传文件的信息 74 @Bean 75 public MultipartResolver multipartResolver() { 76 CommonsMultipartResolver resolver = new CommonsMultipartResolver(); 77 resolver.setDefaultEncoding("UTF-8"); 78 resolver.setMaxUploadSize(10485760000L); 79 resolver.setMaxInMemorySize(40960); 80 return resolver; 81 } 82 83 // 配置静态文件处理 84 @Override 85 public void addResourceHandlers(ResourceHandlerRegistry registry){ 86 87 /** 88 * addResourceHandler 指的是对外暴露的访问路径 89 * addResourceLocations 指的是文件放置的目录 90 * */ 91 registry.addResourceHandler("/assets/**") 92 .addResourceLocations("classpath:/assets/"); 93 94 // href 链接方式 下载文件 95 registry.addResourceHandler("/files/**") 96 .addResourceLocations("classpath:/files/"); 97 98 /** 99 * 解决 No handler found for GET /favicon.ico 异常 100 * */ 101 registry.addResourceHandler("/favicon.ico") 102 .addResourceLocations("classpath:/favicon.ico"); 103 104 } 105 106 // 重写 configurePathMatch ,改变路径参数匹配 107 @Override 108 public void configurePathMatch(PathMatchConfigurer configurer) { 109 110 /** 111 * Spring mvc 默认 如果路径参数后面带点,如 “/mm/nn/xx.yy” 后面的yy值将被忽略 112 * 加入下面的配置,就不会忽略“.”后面的参数了 113 * */ 114 configurer.setUseSuffixPatternMatch(false); 115 116 } 117 118 // 119 // // 负责读取二进制格式的数据和写出二进制格式的数据; 120 // @Bean 121 // public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() { 122 // 123 // return new ByteArrayHttpMessageConverter(); 124 // 125 // } 126 // 127 // // 负责读取字符串格式的数据和写出字符串格式的数据; 128 // @Bean 129 // public StringHttpMessageConverter stringHttpMessageConverter() { 130 // 131 // StringHttpMessageConverter messageConverter = new StringHttpMessageConverter(); 132 // messageConverter.setDefaultCharset(Charset.forName("UTF-8")); 133 // return messageConverter; 134 // 135 // } 136 // 137 // // 负责读取资源文件和写出资源文件数据; 138 // @Bean 139 // public ResourceHttpMessageConverter resourceHttpMessageConverter() { 140 // 141 // return new ResourceHttpMessageConverter(); 142 // 143 // } 144 // 145 // /** 146 // * 负责读取form提交的数据 147 // * 能读取的数据格式为 application/x-www-form-urlencoded, 148 // * 不能读取multipart/form-data格式数据; 149 // * 负责写入application/x-www-from-urlencoded和multipart/form-data格式的数据; 150 // */ 151 // @Bean 152 // public FormHttpMessageConverter formHttpMessageConverter() { 153 // 154 // return new FormHttpMessageConverter(); 155 // 156 // } 157 // 158 // // 负责读取和写入json格式的数据; 159 // /** 160 // * 配置 fastjson 中实现 HttpMessageConverter 接口的转换器 161 // * FastJsonHttpMessageConverter 是 fastjson 中实现了 HttpMessageConverter 接口的类 162 // */ 163 // @Bean(name = "fastJsonHttpMessageConverter") 164 // public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() { 165 // // 166 // String txtHtml = "text/html;charset=UTF-8"; 167 // String txtJson = "text/json;charset=UTF-8"; 168 // String appJson = "application/json;charset=UTF-8"; 169 // 170 // // 这里顺序不能反,一定先写 text/html,不然 IE 下会出现下载提示 171 // List<MediaType> mediaTypes = new ArrayList<>(); 172 // mediaTypes.add(MediaType.parseMediaType(txtHtml)); 173 // mediaTypes.add(MediaType.parseMediaType(txtJson)); 174 // mediaTypes.add(MediaType.parseMediaType(appJson)); 175 // 176 // // 加入支持的媒体类型,返回 contentType 177 // FastJsonHttpMessageConverter fastjson = new FastJsonHttpMessageConverter(); 178 // fastjson.setSupportedMediaTypes(mediaTypes); 179 // return fastjson; 180 // 181 // } 182 // 183 // // 负责读取和写入 xml 中javax.xml.transform.Source定义的数据; 184 // @Bean 185 // public SourceHttpMessageConverter sourceHttpMessageConverter() { 186 // 187 // return new SourceHttpMessageConverter(); 188 // 189 // } 190 // 191 // // 负责读取和写入xml 标签格式的数据; 192 // @Bean 193 // public Jaxb2RootElementHttpMessageConverter jaxb2RootElementHttpMessageConverter() { 194 // 195 // return new Jaxb2RootElementHttpMessageConverter(); 196 // 197 // } 198 // 199 // // 注册消息转换器 200 // /** 201 // * 重写 configureMessageConverters 会覆盖掉 spring mvc 默认注册的多个 HttpMessageConverter 202 // * 所以 推荐使用 extendMessageConverter 203 // * */ 204 // /** 205 // * Error: 206 // * 400:(错误请求) 服务器不理解请求的语法。 207 // * 415:(不支持的媒体类型) 请求的格式不受请求页面的支持。 208 // */ 209 // @Override 210 // public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 211 // 212 // converters.add(this.byteArrayHttpMessageConverter()); 213 // converters.add(this.stringHttpMessageConverter()); 214 // converters.add(this.resourceHttpMessageConverter()); 215 // converters.add(this.formHttpMessageConverter()); 216 // converters.add(this.fastJsonHttpMessageConverter()); 217 // converters.add(this.sourceHttpMessageConverter()); 218 // converters.add(this.jaxb2RootElementHttpMessageConverter()); 219 // 220 // } 221 222 // 自定义 HttpMessageConverter 223 @Bean 224 public CustomMessageConverter customMessageConverter(){ 225 226 return new CustomMessageConverter(); 227 228 } 229 230 // 负责读取和写入json格式的数据; 231 /** 232 * 配置 fastjson 中实现 HttpMessageConverter 接口的转换器 233 * FastJsonHttpMessageConverter 是 fastjson 中实现了 HttpMessageConverter 接口的类 234 */ 235 @Bean(name = "fastJsonHttpMessageConverter") 236 public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() { 237 // 238 String txtHtml = "text/html;charset=UTF-8"; 239 String txtJson = "text/json;charset=UTF-8"; 240 String appJson = "application/json;charset=UTF-8"; 241 242 // 这里顺序不能反,一定先写 text/html,不然 IE 下会出现下载提示 243 List<MediaType> mediaTypes = new ArrayList<>(); 244 mediaTypes.add(MediaType.parseMediaType(txtHtml)); 245 mediaTypes.add(MediaType.parseMediaType(txtJson)); 246 mediaTypes.add(MediaType.parseMediaType(appJson)); 247 248 // 加入支持的媒体类型,返回 contentType 249 FastJsonHttpMessageConverter fastjson = new FastJsonHttpMessageConverter(); 250 fastjson.setSupportedMediaTypes(mediaTypes); 251 return fastjson; 252 253 } 254 255 /** 256 * 重写 extendMessageConverters 方法,仅添加自定义 HttpMessageConverter 257 * 不覆盖默认注册的 HttpMessageConverter 258 * */ 259 @Override 260 public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { 261 262 converters.add(customMessageConverter()); 263 converters.add(fastJsonHttpMessageConverter()); 264 265 } 266 267 // 拦截器 bean 268 @Bean 269 public TimerInterceptor timerInterceptor(){ 270 271 return new TimerInterceptor(); 272 273 } 274 275 // 重写 addInterceptors 注册拦截器 276 @Override 277 public void addInterceptors(InterceptorRegistry registry) { 278 279 registry.addInterceptor(timerInterceptor()); 280 281 } 282 283 }
3.index.jsp
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <title>LM Solution</title> 5 </head> 6 7 <body> 8 <h3>Spring MVC 仿 Spring Boot</h3> 9 <a href="/excel"> Excel </a><br> 10 <a href="/upload">文件上传下载</a><br> 11 <a href="/ImageValidateCodeLogin">登录--图片验证码</a><br> 12 <a href="/restfulapi">Rest API</a><br> 13 <a href="/jaxwsri">Jax-Ws RI</a><br> 14 <a href="/redis">redis option by jedis</a><br> 15 <a href="/mybatisPage">MyBatis</a><br> 16 <a href="/advice/globalHandlerAdvice"> GlobalHandlerAdvice --> GlobalExceptionHandle --> ErrorPage </a><br> 17 <a href="/messageconverter"> 自定义 HttpMessageConverter </a><br> 18 <a href="/sse">Server Sent Event</a> 19 </body> 20 </html>
4.upload.jsp
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 3 <html> 4 <head> 5 <title>File Upload & Download</title> 6 <script src="/assets/js/jquery-2.1.4.min.js"></script> 7 <script src="/assets/js/ajaxfileupload.js"></script> 8 </head> 9 <body> 10 <h3>文件上传</h3> 11 <h3>方式一:采用 fileUpload_multipartFile , file.transferTo 来保存上传的文件</h3> 12 <form name="form1" 13 action="/FileUpload/fileUpload_multipartFile" 14 method="post" 15 enctype="multipart/form-data"> 16 <input type="file" name="file_upload"> 17 <input type="submit" value="上传"> 18 </form> 19 <hr> 20 <h3>方式二:采用 fileUpload_multipartRequest file.transferTo 来保存上传文件</h3> 21 <form name="form2" 22 action="/FileUpload/fileUpload_multipartRequest" 23 method="post" 24 enctype="multipart/form-data"> 25 <input type="file" name="file_upload"> 26 <input type="submit" value="上传"> 27 </form> 28 <hr> 29 <h3>方式三:采用 CommonsMultipartResolver file.transferTo 来保存上传文件</h3> 30 <form name="form3" 31 action="/FileUpload/fileUpload_CommonsMultipartResolver" 32 method="post" 33 enctype="multipart/form-data"> 34 <input type="file" name="file_upload"> 35 <input type="submit" value="上传"> 36 </form> 37 <hr> 38 <h3>方式四:通过流的方式上传文件</h3> 39 <form name="form4" 40 action="/FileUpload/fileUpload_stream" 41 method="post" 42 enctype="multipart/form-data"> 43 <input type="file" name="file_upload"> 44 <input type="submit" value="上传"> 45 </form> 46 <hr> 47 <h3>方式五:通过ajax插件 ajaxfileupload.js 来异步上传文件</h3> 48 <h5>注:已上传成功,只是js返回时会报错。</h5> 49 <form name="form5" 50 enctype="multipart/form-data"> 51 <input type="file" id="file_AjaxFile" name="file_AjaxFile"> 52 <input type="button" value="上传" onclick="fileUploadAjax()" > 53 <span id="sp_AjaxFile"></span> 54 <br> 55 <%--上传进度:<span id="sp_fileUploadProgress">0%</span>--%> 56 </form> 57 <script type="text/javascript"> 58 // 59 var progressInterval=null; 60 var i=0; 61 // 62 function fileUploadAjax() { 63 if($("#file_AjaxFile").val().length>0){ 64 // progressInterval=setInterval(getProgress(),500); 65 $.ajaxFileUpload({ 66 // 用于文件上传的服务器端请求地址 67 url:'/FileUpload/fileUpload_ajax', 68 type:'post', 69 // 一般设置为false 70 secureuri:false, 71 // 文件上传空间的id属性 <input type="file" id="file1" name="file" /> 72 fileElementId:'file_AjaxFile', 73 // 返回值类型 一般设置为json 74 dataType:'application/json', 75 // 服务器成功响应处理函数 76 success:function (data) { 77 var jsonObject=eval('('+data+')'); 78 $("#sp_AjaxFile").html("Upload Success ! filePath:"+jsonObject.filePath); 79 }, 80 // 服务器响应失败处理函数 81 error:function (data,status,e) { 82 alert(e); 83 } 84 }); 85 }else { 86 alert("请选择文件!"); 87 } 88 } 89 </script> 90 <hr> 91 <h3>方式六:多文件上传 采用 MultipartFile[] multipartFile 上传文件方法</h3> 92 <h5>注:三个文件都选择上。</h5> 93 <form name="form5" 94 action="/FileUpload/fileUpload_spring_list" 95 method="post" 96 enctype="multipart/form-data"> 97 <input type="file" name="file_upload"> 98 <input type="file" name="file_upload"> 99 <input type="file" name="file_upload"> 100 <input type="submit" value="上传多个"/> 101 </form> 102 <hr> 103 <h3>方式七:通过 a 标签的方式进行文件下载</h3> 104 <a href="/files/download/mst.txt">通过 a 标签下载文件 mst.txt</a> 105 <hr> 106 <h3>方式八:通过 Response 文件流的方式下载文件</h3> 107 <a href="/FileUpload/fileDownload_servlet">通过 文件流 的方式下载文件 mst.txt</a> 108 </body> 109 </html>
5.FileUploadController.java
1 package lm.solution.web.controller.fileupload; 2 3 import lm.solution.common.file.Files_Utils_DG; 4 import org.springframework.stereotype.Controller; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RequestMethod; 7 import org.springframework.web.bind.annotation.RequestParam; 8 import org.springframework.web.bind.annotation.ResponseBody; 9 import org.springframework.web.multipart.MultipartFile; 10 import org.springframework.web.multipart.MultipartHttpServletRequest; 11 import org.springframework.web.multipart.commons.CommonsMultipartResolver; 12 13 import javax.servlet.http.HttpServletRequest; 14 import javax.servlet.http.HttpServletResponse; 15 import java.util.Iterator; 16 17 18 /** 19 * 使用 MultipartFile 接收上传文件 20 * */ 21 @Controller 22 @RequestMapping(value = "/FileUpload/*") 23 public class FileUploadController { 24 25 /** 26 * 方式一 27 * 采用 fileUpload_multipartFile , file.transferTo 来保存上传的文件 28 * */ 29 @ResponseBody 30 @RequestMapping(value = "fileUpload_multipartFile") 31 public String fileUpload_multipartFile( 32 HttpServletRequest request, 33 @RequestParam("file_upload") MultipartFile multipartFile){ 34 35 // 调用保存文件的帮助类进行保存文件,并返回文件的相对路径 36 String filePath= Files_Utils_DG.FileUpload_transferTo_spring(request,multipartFile,"/files/upload"); 37 38 return "{'TFMark':'true','Msg':'upload success !','filePath':'"+filePath+"'}"; 39 40 } 41 42 /** 43 * 方式二 44 * 采用 fileUpload_multipartRequest file.transferTo 来保存上传文件 45 * 参数不写 MultipartFile multipartFile 在request请求里面直接转成multipartRequest,从multipartRequest中获取到文件流 46 * */ 47 @ResponseBody 48 @RequestMapping(value = "fileUpload_multipartRequest") 49 public String fileUpload_multipartRequest(HttpServletRequest request){ 50 51 // 将request转成MultipartHttpServletRequest 52 MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest)request; 53 // 页面控件的文件流,对应页面控件 input file_upload 54 MultipartFile multipartFile=multipartRequest.getFile("file_upload"); 55 // 调用保存文件的帮助类进行保存文件,并返回文件的相对路径 56 String filePath=Files_Utils_DG.FileUpload_transferTo_spring(request,multipartFile,"/files/upload"); 57 58 return "{'TFMark':'true','Msg':'upload success !','filePath':'"+filePath+"'}"; 59 60 } 61 62 /** 63 * 方式三 64 * 采用 CommonsMultipartResolver file.transferTo 来保存上传文件 65 * 自动扫描全部的input表单 66 * */ 67 @ResponseBody 68 @RequestMapping(value = "fileUpload_CommonsMultipartResolver") 69 public String fileUpload_CommonsMultipartResolver(HttpServletRequest request){ 70 71 // 将当前上下文初始化给 CommonsMultipartResolver (多部分解析器) 72 CommonsMultipartResolver multipartResolver=new CommonsMultipartResolver(request.getSession().getServletContext()); 73 74 // 检查form中是否有enctype="multipart/form-data" 75 if(multipartResolver.isMultipart(request)){ 76 // 将request变成多部分request 77 MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request; 78 // 获取multiRequest 中所有的文件名 79 Iterator iter=multipartRequest.getFileNames(); 80 while (iter.hasNext()){ 81 // 一次遍历所有文件 82 MultipartFile multipartFile=multipartRequest.getFile(iter.next().toString()); 83 // 调用保存文件的帮助类进行保存文件,并返回文件的相对路径 84 String fileName=Files_Utils_DG.FileUpload_transferTo_spring(request,multipartFile,"/files/upload"); 85 86 System.out.println(fileName); 87 } 88 } 89 90 return "upload success !"; 91 } 92 93 /** 94 * 方式四 95 * 通过流的方式上传文件 96 * */ 97 @ResponseBody 98 @RequestMapping("fileUpload_stream") 99 public String upFile( 100 HttpServletRequest request, 101 @RequestParam("file_upload") MultipartFile multipartFile){ 102 103 String filePath=Files_Utils_DG.FilesUpload_stream(request,multipartFile,"/files/upload"); 104 105 return "{'TFMark':'true','Msg':'upload success !','filePath':'"+filePath+"'}"; 106 107 } 108 109 /** 110 * 方式五 111 * 采用 fileUpload_ajax , file.transferTo 来保存上传的文件 异步 112 * */ 113 @ResponseBody 114 @RequestMapping( 115 value = "fileUpload_ajax", 116 method = RequestMethod.POST, 117 produces = "application/json;charset=UTF-8") 118 public String fileUpload_ajax( 119 HttpServletRequest request, 120 @RequestParam("file_AjaxFile") MultipartFile multipartFile){ 121 122 String filePath=Files_Utils_DG.FileUpload_transferTo_spring(request,multipartFile,"/files/upload"); 123 124 return "{'TFMark':'true','Msg':'upload success !','filePath':'"+filePath+"'}"; 125 126 } 127 128 /** 129 * 方式六 130 * 多文件上传 131 * 采用 MultipartFile[] multipartFile 上传文件方法 132 * */ 133 @ResponseBody 134 @RequestMapping(value = "fileUpload_spring_list") 135 public String fileUpload_spring_list( 136 HttpServletRequest request, 137 @RequestParam("file_upload") MultipartFile[] multipartFile){ 138 139 // 判断file数组不能为空并且长度大于0 140 if(multipartFile!=null&& multipartFile.length>0){ 141 // 循环获取file数组中得文件 142 try{ 143 for (int i=0;i<multipartFile.length;i++){ 144 MultipartFile file=multipartFile[i]; 145 // 保存文件 146 String fileName=Files_Utils_DG.FileUpload_transferTo_spring(request,file,"/files/upload"); 147 148 System.out.println(fileName); 149 } 150 151 return "{'TFMark':'true','Msg':'upload success !'}"; 152 }catch (Exception e){ 153 return "{'TFMark':'false','Msg':'参数传递有误!'}"; 154 } 155 } 156 157 return "{'TFMark':'false','Msg':'参数传递有误!'}"; 158 159 } 160 161 /** 162 * 方式八 163 * 文件下载 164 * 165 * @param response 166 * */ 167 @RequestMapping(value = "fileDownload_servlet") 168 public void fileDownload_servlet( 169 HttpServletRequest request, 170 HttpServletResponse response){ 171 172 Files_Utils_DG.FilesDownload_stream(request,response,"/files/download/mst.txt"); 173 174 } 175 176 }
6.Files_Utils_DG.java
1 package lm.solution.common.file; 2 3 import org.springframework.web.multipart.MultipartFile; 4 import javax.servlet.http.HttpServletRequest; 5 import javax.servlet.http.HttpServletResponse; 6 import java.io.*; 7 import java.text.SimpleDateFormat; 8 import java.util.Date; 9 import java.util.UUID; 10 11 public final class Files_Utils_DG { 12 13 /** 14 * 构造函数私有,以使此类不可构造实例 15 */ 16 private Files_Utils_DG() { 17 throw new Error("The class Cannot be instance !"); 18 } 19 20 // 获取绝对路径 21 public static String getServerPath( 22 HttpServletRequest request, 23 String filePath) { 24 25 return request.getSession().getServletContext().getRealPath(filePath); 26 27 } 28 29 // 获取一个以日期命名的文件夹名 ; example:20160912 30 public static String getDataPath() { 31 return new SimpleDateFormat("yyyyMMdd").format(new Date()); 32 } 33 34 // 检查文件夹是否存在,不存在新建一个 35 public static void checkDir(String savePath) { 36 File dir = new File(savePath); 37 if (!dir.exists() || !dir.isDirectory()) { 38 // 不能创建多层目录 39 //dir.mkdir(); 40 // 创建多层目录 41 dir.mkdirs(); 42 } 43 } 44 45 // return an UUID Name parameter (suffix cover '.') example: ".jpg"、".txt" 46 public static String getUUIDName(String suffix) { 47 // make new file name 48 return UUID.randomUUID().toString() + suffix; 49 } 50 51 // return server absolute path(real path) the style is “server absolute 52 // path/DataPath/UUIDName”filePath example "/files/Upload" 53 public static String getAndSetAbsolutePath( 54 HttpServletRequest request, 55 String filePath, 56 String suffix) { 57 58 // example:F:/qixiao/files/Upload/20160912/ 59 String savePath = getServerPath(request, filePath) + File.separator + getDataPath() + File.separator; 60 // check if the path has exist if not create it 61 checkDir(savePath); 62 return savePath + getUUIDName(suffix); 63 64 } 65 66 // get the relative path of files style is 67 // “/filePath/DataPath/UUIDName”filePath example "/files/Upload" 68 public static String getRelativePath(String filePath, String suffix) { 69 // example:/files/Upload/20160912/ 70 return filePath + File.separator + getDataPath() + File.separator + getUUIDName(suffix); 71 } 72 73 /** 74 * spring mvc files Upload method (transferTo method) 75 * MultipartFile use TransferTo method upload 76 * 77 * @param request HttpServletRequest 78 * @param multipartFile MultipartFile(spring) 79 * @param filePath filePath example "/files/Upload" 80 * @return 81 */ 82 public static String FileUpload_transferTo_spring( 83 HttpServletRequest request, 84 MultipartFile multipartFile, 85 String filePath) { 86 87 if (multipartFile != null) { 88 // get files suffix 89 String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")); 90 // filePath+fileName the complex file Name 91 String absolutePath = getAndSetAbsolutePath(request, filePath, suffix); 92 // return relative Path 93 String relativePath = getRelativePath(filePath, suffix); 94 95 try { 96 // save file 97 multipartFile.transferTo(new File(absolutePath)); 98 99 return relativePath; 100 } catch (IOException ie) { 101 ie.printStackTrace(); 102 return null; 103 } 104 105 } else { 106 return null; 107 } 108 109 } 110 111 /** 112 * user stream type save files 113 * 114 * @param request HttpServletRequest 115 * @param multipartFile MultipartFile support CommonsMultipartFile file 116 * @param filePath filePath example "/files/Upload" 117 * @return 118 */ 119 public static String FilesUpload_stream( 120 HttpServletRequest request, 121 MultipartFile multipartFile, 122 String filePath) { 123 124 if (multipartFile != null) { 125 // get files suffix 126 String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".")); 127 // filePath+fileName the complex file Name 128 String absolutePath = getAndSetAbsolutePath(request, filePath, suffix); 129 // return relative Path 130 String relativePath = getRelativePath(filePath, suffix); 131 try { 132 InputStream inputStream = multipartFile.getInputStream(); 133 FileOutputStream fileOutputStream = new FileOutputStream(absolutePath); 134 // create a buffer 135 byte[] buffer = new byte[4096]; 136 long fileSize = multipartFile.getSize(); 137 138 if (fileSize <= buffer.length) { 139 buffer = new byte[(int) fileSize]; 140 } 141 142 int line = 0; 143 while ((line = inputStream.read(buffer)) > 0) { 144 fileOutputStream.write(buffer, 0, line); 145 } 146 147 fileOutputStream.close(); 148 inputStream.close(); 149 150 return relativePath; 151 152 } catch (Exception e) { 153 e.printStackTrace(); 154 } 155 } else { 156 return null; 157 } 158 159 return null; 160 } 161 162 /** 163 * @param request HttpServletRequest 164 * @param response HttpServletResponse 165 * @param filePath example "/filesOut/Download/mst.txt" 166 * 167 * @return 168 * */ 169 public static void FilesDownload_stream( 170 HttpServletRequest request, 171 HttpServletResponse response, 172 String filePath){ 173 174 // get server path (real path) 175 String realPath=request.getSession().getServletContext().getRealPath(filePath); 176 File file=new File(realPath); 177 String filenames=file.getName(); 178 InputStream inputStream; 179 try{ 180 inputStream=new BufferedInputStream(new FileInputStream(file)); 181 byte[] buffer=new byte[inputStream.available()]; 182 inputStream.read(buffer); 183 inputStream.close(); 184 response.reset(); 185 // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名 186 response.addHeader("Content-Disposition","attachment;filename="+new String(filenames.replaceAll(" ","").getBytes("UTF-8"),"iso8859-1")); 187 response.addHeader("Content-Length",""+file.length()); 188 OutputStream os=new BufferedOutputStream(response.getOutputStream()); 189 response.setContentType("application/octet-stream"); 190 os.write(buffer); 191 os.flush(); 192 os.close(); 193 }catch (Exception e){ 194 e.printStackTrace(); 195 } 196 197 } 198 199 200 201 }
蒙
2018-05-16 22:22 周三