上传文件这个功能用的比较多,不难,但是每次写都很别扭。记录在此,以备以后copy用。
package com.**.**.**.web.api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
/**
* @Author: zyydd
* @Date: 2019/10/12 14:18
*/
@RestController
@RequestMapping(value = "/api/v1", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class UploadController {
private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
/**
* 桶名,取配置
*/
@Value("${jss.bucket}")
private String bucket;
private static String key = "file";
private static String springProperties = "application.properties";
@ResponseBody
@RequestMapping(value = "/upload/{fileType}", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
@ApiOperation(value = "文件上传", notes = "文件上传,form-data,key=file;fileType:pic、file", response = String.class, tags = {"UploadController",})
public String uploadFile(HttpServletRequest request, @PathVariable(value = "fileType") String fileType) {
String result = "";
String fileAbsolutePath = "";
try {
logger.info("uploadFile begin! fileType={}", fileType);
//写本地文档
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
MultipartFile multipartFile = multipartHttpServletRequest.getFile(key);
String fileName = multipartFile.getOriginalFilename();
//文件名称加随机数处理,避免重名
fileName = fileName.substring(0, fileName.lastIndexOf(".")) + "_" + System.currentTimeMillis() % 1000 + fileName.substring(fileName.lastIndexOf("."));
fileAbsolutePath = getUploadPath() + fileName;
writeFile(fileAbsolutePath, multipartFile.getBytes());
//上传各种云的utils,返回一个上传后可供下载的url,注解掉,按需处理。传入本地文件的绝对路径以及云上桶名
String url = AmazonS3Utils.uploadFileToS3(fileAbsolutePath, bucket);
if (StringUtils.isNotBlank(url)) {
//持久化file数据到数据库,返回数据ID,前台页面根据ID进行挂载,按需处理
Long fileId = fileService.insertFile(url, fileType);
result = fileId + "";
} else {
logger.error("上传云失败,文件本地路径={}", fileAbsolutePath);
result = "上传云失败";
}
} catch (Exception e) {
result = "上传异常";
logger.error("uploadFile exception!", e);
} finally {
//上传完成之后,确保删除本地文件
try {
if (StringUtils.isNotBlank(fileAbsolutePath)) {
File f = new File(fileAbsolutePath);
if (f.exists()) {
f.delete();
}
}
} catch (Exception e) {
logger.error("delete file exception", e);
result = "删除本地文件异常";
}
logger.info("uploadFile end! result={}", result);
return result;
}
}
//通过spring的配置文件,来获取war包的绝对路径,并将文件上传到预先准备的文件夹下
private String getUploadPath() {
URL url = this.getClass().getClassLoader().getResource(springProperties);
String uploadPath = url.getPath().replace(springProperties, "upload/");
return uploadPath;
}
public static void writeFile(String fileAbsolutePath, byte[] content) throws IOException {
FileOutputStream fos = new FileOutputStream(fileAbsolutePath);
fos.write(content);
fos.close();
}
}
相应的,postMan中,调用的示例截图如下