欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【SpringBoot】文件上传(基础上传、上传文件限制、上传多个文件)

程序员文章站 2022-06-03 13:12:08
...

文件上传


文件上传是Web开发非常重要的操作

结合SpringBoot实现文件上传操作

1、基础上传

SpringBoot采用FileUpload组件实现上传处理,在控制器中可以使用MultipartFile类进行接收。

FileUpload上传 MultipartFile接收

1、建立上传控制器UploadController,利用MultipartFile将上传文件保存在本地磁盘。

一个上传文件的接口,访问接口选择把要上传的文件利用MultipartFile上传保存在本地磁盘中。

@Controller
public class UploadController {
	//访问http://localhost//upload_pre 显示upload.html页面
    @GetMapping("/upload_pre")
    public String uploadPre() { // 通过model可以实现内容的传递
        return "upload";
    }

    //upload
    @PostMapping("/upload")
    @ResponseBody
    public Object upload(String name, MultipartFile photo) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        if (photo != null) {    // 现在有文件上传
        	//姓名
            map.put("name-param", name);
            //文件名
            map.put("photo-name", photo.getName());
            //文件类型 content-type: "image/png",
            map.put("content-type", photo.getContentType());
            //文件大小
            map.put("photo-size", photo.getSize());
            //eg: UUID + . + png
            String fileName = UUID.randomUUID() + "."
                    + photo.getContentType().substring(
                    photo.getContentType().lastIndexOf("/") + 1);    // 创建文件名称
			//文件路径  位置 + 文件名
			String filePath = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                    .getRequest().getServletContext().getRealPath("/") + fileName;
            //文件路径
			map.put("photo-path", filePath);
            File saveFile = new File(filePath);
            photo.transferTo(saveFile);        // 文件保存
            return map;
        } else {
            return "nothing";
        }
    }
}


2、建立src/main/view/templates/upload.html页面

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>文件上传</title>
	<script type="text/javascript" th:src="@{/js/main.js}"></script> 
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>
	<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
		姓名:<input type="text" name="name"/><br/>
		照片:<input type="file" name="photo"/><br/>
		<input type="submit" value="上传"/>
	</form>
</body>
</html>

执行

upload.html页面表单填入姓名和选择图片点击上传向upload接口传递了姓名(文本)和图片(二进制数据)两个数据信息。控制器接收到此请求信息后,返回JSON格式信息

{
photo-size: 23902,
content-type: "image/png",
photo-path: "C:\Windows\Temp\tomcat-docbase.6786357466203986968.80\2a220798-ecbe-4fae-a1c9-485d75d7dfe1.png",
photo-name: "photo",
name-param: "liuawen"
}

2、上传文件限制

在实际项目开发中,需要对用户上传文件的大小进行限制,这样才可以保证服务器的资源不被浪费。 配置yml实现上传限制

1、修改application.yml配置文件,增加上传限制。

application.yml

spring:
  http:
    multipart:
      enabled: true           # 启用http上传
      max-file-size: 10MB     # 设置支持的单个上传文件的大小限制
      max-request-size: 20MB  # 设置最大的请求的文件大小,设置总体大小请求
      file-size-threshold: 512KB   # 当上传文件达到指定配置量的时候会将文件内容写入磁盘
      location: /             # 设置上传的临时目录

2、对于上传限制,也可以利用Bean实现同样的效果。·

cn.liuawen.config UploadConfig.java

@Configuration
public class UploadConfig {
	@Bean
	public MultipartConfigElement getMultipartConfig() {
		MultipartConfigFactory config = new MultipartConfigFactory() ;
		config.setMaxFileSize("100KB"); 			// 设置上传文件的单个大小限制
		config.setMaxRequestSize("20MB"); 		// 设置总的上传的大小限制
		config.setLocation("/"); 				// 设置临时保存目录
		return config.createMultipartConfig() ;	// 创建一个上传配置
	}
}

设置上传文件的单个大小限制

为了测试我把上传文件的单个大小限制设置小了点 看测试是否有异常

上传了个195KB的

http://localhost/upload

上传出错后页面执行的效果

错误路径:http://localhost/upload

错误信息:Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field photo exceeds its maximum permitted size of 102400 bytes.

错误 图片太大了,用户上传的内容超过了配置的限制,全局异常处理 。

3、上传多个文件

如果要进行多个文件的上传,需要通过MultipartHttpServletRequest进行文件接收。

1、修改upload.html页面,定义多个文件上传控件。

upload.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>SpringBoot多文件上传</title>
	<script type="text/javascript" th:src="@{/js/main.js}"></script> 
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>

	<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
		姓名:<input type="text" name="name"/><br/>
<!--		选择多个文件上传  这里是一个个的呀-->
		照片1:<input type="file" name="photo"/><br/>
		照片2:<input type="file" name="photo"/><br/>
		照片3:<input type="file" name="photo"/><br/>
		<input type="submit" value="上传"/>
	</form>
</body>
</html>

2、修改UploadController控制器,实现多个文件上传。

@Controller
public class UploadController {
	@GetMapping("/upload_pre")
	public String uploadPre() { // 通过model可以实现内容的传递
		return "upload";
	}
	@PostMapping("/upload")
	@ResponseBody
	public Object upload(String name, HttpServletRequest request) {  
		List<String> result = new ArrayList<String>() ;
		//多个文件上传  就只是简单的多文件上传保存在本地的磁盘
		if (request instanceof MultipartHttpServletRequest) {
			MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest) request;
			//<input type="file" name="photo"/>
			List<MultipartFile> files = mrequest.getFiles("photo");
			Iterator<MultipartFile> iter = files.iterator();
			while (iter.hasNext()) {
				MultipartFile photo = iter.next() ;		// 取出每一个上传文件
				try {
					result.add(this.saveFile(photo)) ;		// 保存上传信息
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return result ; 
	}
	/**
	 * 文件保存处理
	 * @param file 上传文件
	 * @return 文件保存路径 
	 * @throws Exception 上传异常
	 */
	public String saveFile(MultipartFile file) throws Exception {
		String path = "nothing" ;
		if (file != null) {					// 有文件上传
			if (file.getSize() > 0) {
				String fileName = UUID.randomUUID() + "."
						+ file.getContentType().substring(
								file.getContentType().lastIndexOf("/") + 1);	// 创建文件名称
				path = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
						.getRequest().getServletContext().getRealPath("/") + fileName;
				File saveFile = new File(path) ;
				file.transferTo(saveFile);		// 文件保存
			}
		} 
		return path ;
	}
}


3、测试

http://localhost/upload_pre

【SpringBoot】文件上传(基础上传、上传文件限制、上传多个文件)
http://localhost/upload

[
"C:\Windows\Temp\tomcat-docbase.1489099008397591870.80\c97e9432-4716-4ef8-93d0-d18f3b4ab74d.png",
"C:\Windows\Temp\tomcat-docbase.1489099008397591870.80\09bab86d-44bd-426e-8d5c-9d7c17929ae7.png",
"C:\Windows\Temp\tomcat-docbase.1489099008397591870.80\5d30e2de-f83a-4113-8c96-69b3e92de086.png"
]

【SpringBoot】文件上传(基础上传、上传文件限制、上传多个文件)

为了方便文件上传,就简单在控制器类中定义了一个saveFile()方法,以进行文件的保存,同时利用此方法返回了上传文件的保存路径。

这里的保存上传图片都是保存到本地磁盘的,
假的上传????
实际开发不是这样的,在当今的项目开发中,最流行的设计理念是高可用、高并发、分布式设计,所以在实际项目中需要搭建专门的图片服务器进行上传资源的保存。

图片服务器集群

4、参考资料

简单记录

1、名师讲坛:Java微服务架构实战(SpringBoot+SpringCloud+Docker+RabbitMQ)- 李兴华