写在前面
谈到文件上传,首先要说业务逻辑,如果上传的文件大家都可以看(比如广告或者首页的banner)等,那么我们就把图片放在静态资源区(与css,js一样的位置)中,如果文件是受保护的(像用户只能查看自己上传的照片),那么我们就把它存放在服务器中的某个专门存放图片的位置。
本例分别展示了存放在两个位置的上传文件的方法,上传之后,作为延伸,还添加了查看上传的文件以及下载已经上传的文件的功能。
准备工作
配置SpringMVC,导入commons包
在mvc-servlet.xml中配置文件上传解析器
1
2
3
4
5
6
|
<!--文件上传解析器--> < bean id = "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver" > < property name = "maxUploadSize" value = "1000000" /> < property name = "defaultEncoding" value = "UTF-8" /> </ bean > |
存放在静态资源区
1、存放位置:
存放在项目中,所以路径为相对项目的路径。
/{yourproject}/webapp/static/img
2、配置响应的handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
@Controller public class UploadController { @GetMapping ( "/upload" ) public String UploadHandler() { return "upload" ; } @PostMapping ( "/upload/static" ) public void wriToStatic(HttpServletRequest request, RedirectAttributes redirectAttributes, @RequestParam ( "fileName" ) MultipartFile file) { if (!file.isEmpty()) { //获取目标文件夹 String path = request.getServletContext().getRealPath( "/" ) + "static/img/" ; //获取用户上传的源文件名 String fileName = file.getOriginalFileName(); //新建文件 File file1 = new File(path, fileName); //将文件写入 file.transferTo(file1); redirectAttributes.addFlashAttribute( "message" , "upload to static success" ); return "redirect:/upload" ; } else { redirectAttributes.addFlashAttribute( "message" , "upload file can not be empty" ); return "redirect:/upload" ; } } } |
存放在服务器
1、本例存放位置:
存放在服务器某个位置,与项目无关,所以地址为绝对路径。
/Users/mac/Desktop/imgtemp/, 为目录的绝对路径。
2、配置响应的handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
... @PostMapping ( "/upload/disk" ) public String writeToDisk(HttpServletRequest request, @RequestParam ( "fileName" ) MultipartFile file, RedirectAttributes redirectAttributes) { if (!file.isEmpty()) { //获取源文件名 String fileName = file.getOriginalFileName(); //获取保存文件文件夹路径 String path = "/Users/mac/Desktop/imgtemp/" ; //新建文件 File file1 = new File(path,fileName); //写入文件 file.transferTo(file1); } } ... |
延伸部分(文件的查看及下载)
由于响应是要以流的形式传递文件,我们需要正确的设置响应的MIMIE类型才能被浏览器正确的解析,应用程序文件的默认MIMIE类型为 application/octet-stream,MIME设置为该值后,浏览器不会自动执行或询问执行这类文件,会以对待附件的形式直接将文件下载至本地。
更多关于MIMIE的解读请查看这篇文章
如果我们如果想自定义下载文件的名字,那么就需要设置Content-Disposition消息。
Content-Disposition 消息头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。
更过关于Content-Disposition的解读请查看这篇文章
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
... @GetMapping ( "/download/byDefault" ) public void getImgByDefault( @RequestParam String fileName, @RequestParam (required= false ,defaultValue= "" ) String saveName), HttpServletResponse response { if (StringUtils.isEmpty(fileName)) { response.sendError( 404 ); return ; } //文件存放的路径 String path = "/Users/mac/Desktop/imgtemp/" ; //新建文件 File file = new File(path,fileName); if (!file.exists()) { response.sendError( 404 ); return ; } //如果请求参数saveName不为空,进行文件的下载 if (!StringUtils.isEmpty(saveName)) { //设置响应长度 response.setContentLength(( int )file.length()); //设置响应的MIME类型为application/octet-stream response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); saveName = new String(saveName.getBytes( "UTF-8" ), "ISO8859-1" ); //设置content-disposition为attachment;fileName=saveName response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" +saveName+ "\"" ); } //读取文件 InputStream is = new FileInputStream(file); OutputStream os = response.getOutputStream(); //将文件以流的形式输出 IOUtils.copy(is,os); os.flush(); os.close(); is.close(); } |
我们还可以使用SpringMVC自带的 ByteArrayHttpMessageConverter 转化器来将文件输出,该转换器实现 HttpMessageConverter 接口。可读取所有MIME的请求信息,响应信息的MIME为 application/octet-stream
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
... @GetMapping ( "/download/byConvert" ) public HttpEntity< byte []> getImgByConvert( @RequestParam String fileName, @RequestParam (required= false ,defaultValue= "" ) String saveName) { if (StringUtils.isEmpty(fileName)) { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } String path = "/Users/mac/Desktop/imgtemp/" ; File file = new File(path,fileName); if (!file.exists()) { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } HttpHeaders headers = new HttpHeaders(); if (!StringUtils.isEmpty(saveName)) { headers.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); headers.setContentLength(file.length()); saveName = new Sting(saveName.getBytes( "UTF-8" ), "ISO8859-1" ); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=\"" + saveName + "\"" ); } else { headers.setContentType(MediaType.IMAGE_PNG); } return new HttpEntity<>(FileCopyUtils.copyToByteArray(file),headers); } |
upload.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
<%@ page contentType= "text/html;charset=UTF-8" language= "java" %> <% @taglib prefix= "form" uri= "http://www.springframework.org/tags/form" %> <%@ taglib prefix= "c" uri= "http://java.sun.com/jsp/jstl/core" %> <!doctype html> <html> <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>Document</title> <link rel= "stylesheet" href= "/static/bootstrap-3.3.5-dist/css/bootstrap.css" rel= "external nofollow" > </head> <body> <div class = "container" > <h1 class = "text-center" >上传文件撒</h1> <c: if test= "${not empty message}" > <h2>${message}</h2> </c: if > <form:form enctype= "multipart/form-data" action= "/upload/static" > <p class = "text-info" >上传至/web/ static </p> <label for = "" >上传文件:</label> <input type= "file" name= "uploadFile" > <button class = "btn btn-default" >提交</button> </form:form> <form:form enctype= "multipart/form-data" action= "/upload/disk" > <p class = "text-info" >上传至Disk</p> <label for = "" >上传文件</label> <input type= "file" name= "uploadFile" > <button class = "btn btn-default" >提交</button> </form:form> <div class = "container" > <button class = "btn btn-default" > <a href= "/download/byDefault?fileName=dubbo.png" rel= "external nofollow" target= "_blank" >使用默认方式查看上传至Disk的dubbo图片</a> </button> <button class = "btn btn-default" > <a href= "/download/byDefault?fileName=dubbo.png&saveName=dubb.png" rel= "external nofollow" >使用默认方式下载dubbo图片</a> </button> </div> <div class = "container" > <button class = "btn btn-default" > <a href= "/download/byConvert?fileName=dubbo.png" rel= "external nofollow" target= "_blank" >使用MVC转化器查看上传至Disk的dubbo图片</a> </button> <button class = "btn btn-default" > <a href= "/download/byConvert?fileName=dubbo.png&saveName=dub.png" rel= "external nofollow" >使用MVC转化器下载上传至Disk的dubbo图片</a> </button> </div> </div> </body> </html> |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://www.jianshu.com/p/95d3de3523f2