最近项目业务要求上传文件,在网上找了好多版本,感觉适用性太差了,就自己花时间写了一个简单版本的。
不过我写的批量上传并不是多线程同时上传操作,而是遍历依次上传的,所以存在的问题就显而易见了。但对于本次业务已经足够了,有时间再完善。
一. 创建maven项目,并添加依赖
<groupId>com.alibaba</groupId>
<artifactId>upload</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<finalName>SpringWebContent</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
二. 建立结构
简单结构大致如此。其中,需要注意Application启动类要在所有类的外层;
Application:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
application.yml:
server:
port: 9527
prop:
uploadFolder: e:/upload
# 根据自己需求配置. 可以配置ftp服务器连接.
upload.html:需要注意上传条件的“三要素” :enctype,method,type
<body>
<form action="/upload/multiFileUpload" enctype="multipart/form-data" method="post">
<p>文件1:<input type="file" name="file" /></p>
<p>文件2:<input type="file" name="file" /></p>
<p><input type="submit" value="上传" /></p>
</form>
</body>
controller:
@RestController
public class UploadController {
@Value("${prop.uploadFolder}")
private String UPLOAD_FOLDER;
/**
* 上传单个文件
*/
@RequestMapping(value = "/upload/singleFileUpload", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String singleFileUpload(MultipartFile file) {
if (Objects.isNull(file) || file.isEmpty()) {
return "文件为空!";
}
String allName = file.getOriginalFilename();
if(!allName.substring(allName.lastIndexOf(".")).equals(".xlsx")){ //后缀名指定为.xlsx,这里根据需要进行定义
return "文件格式不正确!";
}
try {
byte[] bytes = file.getBytes();
Path path = Paths.get(UPLOAD_FOLDER + "/"+getFilename(allName)); // 文件夹 +/+ 文件完整名称 a.txt
//如果没有files文件夹,则创建
if (!Files.isWritable(path)) {
Files.createDirectories(Paths.get(UPLOAD_FOLDER));
}
//文件写入指定路径
Files.write(path, bytes);
System.out.println("-----------------");
return "文件上传成功";
} catch (IOException e) {
return "文件上传失败";
}
}
/**
* 上传多个文件
* @param: file 和标签name对应,否则无响应
* @return string
*/
@RequestMapping(value = "/upload/multiFileUpload", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String multiFileUpload(MultipartFile[] file) {
String msg = null;
int count = 0;
try {
for (int i = 0; i < file.length; i++) {
if(file[i]!=null){
msg = singleFileUpload(file[i]);
}
if(!msg.equals("文件上传成功")){
count = i;
continue;
}
}
if(count>0){ //说明有失败的
return "第"+count+"个文件上传失败,其他文件上传成功";
}
return msg;
} catch (Exception e) {
return e.getMessage();
}
}
/**
* 时间+随机数+后缀 设置文件名
* @param originalFilename 原名称
* @return string
*/
private String getFilename(String originalFilename){
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); //后缀名 如 .txt
DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
// 将此时时间转换为字符串
String formatDate = format.format(new Date());
// 随机生成文件编号
int random = new Random().nextInt(10000);
// 拼接文件名
String filename = new StringBuffer().append(formatDate).append("_").append(random).append(suffix).toString();
return filename;
}
}
至此,实现了简单批量上传的操作。