文件上传

文件上传是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

在这里插入图片描述
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"
]

在这里插入图片描述

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

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

图片服务器集群

4、参考资料

简单记录

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

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐