写在前面
谈到文件上传,首先要说业务逻辑,如果上传的文件大家都可以看(比如广告或者首页的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