文件上传与存储在开发中的实际应用


1. 前端页面

<form id="form-change-avatar" class="form-horizontal" role="form">
<div class="form-group">
<label class="col-md-2 control-label">选择头像:label>
<div class="col-md-5">
<img id="img-avatar" src="../images/index/user.jpg" class="img-responsive" />
div>
<div class="clearfix">div>
<div class="col-md-offset-2 col-md-4">
<input type="file" name="file">
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input id="btn-change-avatar" type="button" class="btn btn-primary" value="上传" />
div>
div>
form>

2. Controller

public class UserController extends BaseController {
   
   //这里是对文件的一些限制
   /**
    * 头像文件大小的上限值(10MB)
    */
   public static final int AVATAR_MAX_SIZE = 10 * 1024 * 1024;
   /**
    * 允许上传的头像的文件类型
    */
   public static final List<String> AVATAR_TYPES = new ArrayList<String>();
?
   /** 初始化允许上传的头像的文件类型 */
   static {
       AVATAR_TYPES.add("image/jpeg");
       AVATAR_TYPES.add("image/png");
       AVATAR_TYPES.add("image/bmp");
       AVATAR_TYPES.add("image/gif");
  }
   
 
   /**
    * 文件上传功能的实现
    * @param file 从客户端传过来的文件
    * @param session 用于获取存储在session中的信息
    * @return
    */
   @RequestMapping("change_avatar")
   public JsonResult<String> changeAvatar(@RequestParam("file") MultipartFile file, HttpSession session) {
       //首先判断文件是否为空
       if (file.isEmpty()) {
           throw new FileEmptyException("文件为空");
      }
//判断文件大小是否符合规定
       if (file.getSize() > AVATAR_MAX_SIZE){
           throw new FileSizeException("不允许上传超过" + (AVATAR_MAX_SIZE / 1024) + "KB的头像文件");
      }

       //getContentType():获得文件的类型 例如图像类型:image/jpeg
       String type = file.getContentType();
       if (!AVATAR_TYPES.contains(type)){
           throw new FileTypeException("不支持使用该类型的文件作为头像,允许的文件类型:\n" + AVATAR_TYPES);
      }

       //文件会默认存储在.../upload/文件名.png
       String path = session.getServletContext().getRealPath("upload");
?
       //filepath指向这个路径
       File filePath = new File(path);
       //判断是否存在,不存在就新建文件夹
       if (!filePath.exists()){
           filePath.mkdir();
      }
?
       String fileName = FileUtils.getFileName(file);
?
?
       File dest=new File(filePath,fileName);//创建一个空文件
       try {
           file.transferTo(dest);
      } catch (IOException e) {
           throw new FileUploadIOException("文件读写异常");
      }
?
       String avatar="/upload/"+fileName;
?
?
?
       Integer uid = getUidFromSession(session);
       String username = getUsernameFromSession(session);
       userService.changeAvatar(uid,username,avatar);
       return new JsonResult<>(OK,avatar);
?
?
  }
   
   
}
public class FileUtils {
?
   //设置文件的新名字,防止因为文件重名而被覆盖
   public static String getFileName(MultipartFile file) {
       //获取文件名
       String originalFilename = file.getOriginalFilename();
       //断言filename不为空
       assert originalFilename != null;
       //text.jpg
       int index = originalFilename.lastIndexOf(".");
       String suffix = "";
       if (index > 0) {
           //获取文件的后缀格式
           suffix = originalFilename.substring(index);
      }
//通过UUID和suffix结合生成新名字
       return UUID.randomUUID().toString().toUpperCase() + suffix;
?
  }
?
}

3. 调整文件的限制值

2.如果需要调整上传的限制值,直接在启动类中添加getMultipartConfigElement()方法,并且在启动类之前添加@Configuration注解。

package com.cy.store;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.unit.DataSize;
import org.springframework.util.unit.DataUnit;
import javax.servlet.MultipartConfigElement;
?
@Configuration
@SpringBootApplication
@MapperScan("com.cy.store.mapper")
public class StoreApplication {
?
   public static void main(String[] args) {
       SpringApplication.run(StoreApplication.class, args);
  }
?
   @Bean
   public MultipartConfigElement getMultipartConfigElement() {
       MultipartConfigFactory factory = new MultipartConfigFactory();
       // DataSize dataSize = DataSize.ofMegabytes(10);
       // 设置文件最大10M,DataUnit提供5中类型B,KB,MB,GB,TB
       factory.setMaxFileSize(DataSize.of(10, DataUnit.MEGABYTES));
       factory.setMaxRequestSize(DataSize.of(10, DataUnit.MEGABYTES));
       // 设置总上传数据总大小10M
       return factory.createMultipartConfig();
  }
}

3.除了以上编写方法配置上传的上限值以外,还可以通过在application.properties或application.yml中添加配置来实现。

(1) 低版本:1.X

spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=10MB

(2) 高版本:2.X

#方式1
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
#方式2
spring.servlet.multipart.maxFileSize=10MB
spring.servlet.multipart.maxRequestSize=10MB