### 【附】 基于SpringMVC的文件上传(MultipartFile接口)

**1. 创建项目**

创建新项目:

- Group Id:cn.tedu.spring

- Artifact Id:SPRINGMVC-03-UPLOAD

- Packaging:war

然后,按照传统方式完成项目的创建(添加web.xml;添加Tomcat Runtime,复制pom.xml中的依赖,复制web.xml中的配置,复制spring的配置文件。注意:检查spring的配置文件是否存在多余且不可用的配置,如果有,则删除)。

**2. 制作上传页面**

上传文件的页面只要求是html页面即可,不需要是jsp页面(可以使用jsp页面)。

上传使用的控件是:
 


并且,上传时的表单必须配置`enctype`属性,并且请求类型必须是`post`类型:
 

整体设计可以是:

基于SpringMVC的文件上传

请选择您要上传的文件

**3. 添加依赖**

基于SpringMVC的文件上传需要添加`spring-webmvc`依赖,并添加`commons-fileupload`依赖:


		commons-fileupload
		commons-fileupload
		1.4
	

**4. 配置MultipartResolver**

在spring的配置文件中添加:


	
	

注意:此项配置中,``的`id`必须是`multipartResolver`

该``也可以添加更多的配置,但是,不是必须的!

此次项目中,需要开启注解驱动:


	

**5. 开发控制器接收上传请求**

创建控制器类`cn.tedu.spring.FileUploadController`,并添加处理请求的方法:
 

@Controller
	public class FileUploadController {
	
		@RequestMapping("/upload.do")
		public String handleUpload(
			@RequestParam("file") MultipartFile file) {
			return null;
		}
		
	}

注意:客户端提交的上传的文件需要声明为`MultipartFile`类型(这是一个接口类型,实际类型是`CommonsMultipartFile`),并且,需要添加`@RequestParam`注解,如果没有添加该注解,在某些版本中可能会出错。

当然,以上控制器的方法确定后,前端页面中`

`的`action`属性和上传控件的`name`属性应该与之保持一致


		

在控制器中,处理请求的方法中的参数`MultipartFile`其实就是客户选择上传的文件,直接调用`transferTo()`方法将其保存到某个文件即可:
 

@RequestMapping("/upload.do")
	public String handleUpload(
		@RequestParam("file") MultipartFile file) 
			throws IllegalStateException, IOException {
		File dest = new File("d:/12345.png");
		file.transferTo(dest);
		return null;
	}

**6. 关于上传的文件夹**

在处理请求的方法中添加参数`HttpServletRequest`,然后调用该参数对象的`getServletContext().getRealPath("upload")`即可获取到`webapp`下的名为`upload`的文件夹的实际路径,例如`D:\apache-tomcat-7.0.54\wtpwebapps\SPRINGMVC-03-UPLOAD\upload\`。

因为上传的文件大多后续将需要通过http方式被访问,所以,上传文件夹是应该在`webapp`之下!则应该通过以上方式获取文件夹的位置。

**7. 关于上传的文件名**

如果同一个项目中,上传的所有文件都将在同一个文件夹中,则需要保证每个文件的文件名是不相同的,否则,将会出现后续上传的文件会覆盖前序上传的文件!

如果要保证文件名是唯一的,可以使用UUID,也可以使用System.nanoTime(),或使用时间与随机数的组合等等多种方式!

通常,上传的文件的扩展名还是由原文件来决定,即上传过程中,不改变文件的扩展名,通过`MultipartFile`的`getOriginalFilename()`方法可以获取上传的文件的原名(该文件在客户端计算机中的原始名称),然后通过String类的API即可获取文件的扩展名:


	String originalFilename = file.getOriginalFilename();
	int beginIndex = originalFilename.lastIndexOf(".");
	String suffix = "";
	if (beginIndex > 0) {
		suffix = originalFilename.substring(beginIndex);
	}

**8. 关于MultipartFile接口的常用方法**

- `String getOriginalFilename()`:获取原文件名,即文件在客户端计算机中的名称;

- `boolean isEmpty()`:判断上传的文件是否为空,如果在上传表单中没有选中文件,或选中的文件没有内容(0字节),将视为空,则返回true,否则返回false;

- `long getSize()`:获取上传的文件的大小,以字节为单位,可以用于限制上传的文件的大小;

- `String getContentType()`:获取上传的文件的文档类型,其值是文件的MIME类型,可以用于限制上传的文件的类型;

- `InputStream getInputStream()`:获取上传的文件的输入流,主要用于自定义存储文件的过程,当自定义存储时,就不再需要调用`transferTo()`方法了;

- `void transferTo(File dest)`:将上传的文件存储为指定的文件。

**9. 关于MultipartResolver的配置**

在Spring的配置文件中,配置`CommonsMultipartResolver`时,可以为某些属性注入值,来完成某些配置:

- `maxUploadSize`:最大上传尺寸,以字节为单位,假设设置值为10M,则无论一次性上传多少个文件,其总和不允许超过10M;

- `maxUploadSizePerFile`:上传的每个文件的最大尺寸,以字节为单位,假设设置值是10M,如果一次上传多个文件,则每个文件的大小都不可以超过10M,但是,多个文件的总和是可以超过10M的;

- `defaultEncoding`:默认编码。

 

在商城的案例中

@RequestMapping("/change_avatar")
	public ResponseResult changeAvatar(HttpServletRequest request,@RequestParam("file")MultipartFile file){
		if (file.isEmpty()) {
			throw new FileEmptyException("空白文件异常");
		}
		if (!UPLOAD_CONTENT_TYPE.contains(file.getContentType())) {
			throw new FileContentTypeException("文件格式异常");
		}
		if (UPLOAD_MAX_SIZE0) {
			suffix=Originalfilename.substring(beginIndex);
		}
		//确定文件名:uuid/nanoTime/..
		String filename=System.nanoTime()+suffix;
		//创建dest对象new File(parent, filename);
		File dest=new File(parent, filename);
		//执行上传
		try {
			file.transferTo(dest);
		} catch (IllegalStateException e) {
			e.printStackTrace();
			throw new FileIllegalstateException("数据异常");
		} catch (IOException e) {
			e.printStackTrace();
			throw new FileIOException("数据异常");
		}
		//获取uid:getUidFromSession
		Integer uid=getuidFromSession(request.getSession());
		//生成avatar:/UPLOAD_DIR/文件名.扩展名
		String avatar="/"+UPLOAD_DIR+"/"+filename;
		//执行更新:userService.changeAvatar(uid,avatar);
		userservice.changAvatar(uid, avatar);
		//返回成功
		return new ResponseResult<>(SUCCESS,avatar);
	}

 

你可能感兴趣的:(### 【附】 基于SpringMVC的文件上传(MultipartFile接口))