適用 spring mvc, spring boot
Controller代碼:
@PostMapping("/files")
@ResponseStatus(HttpStatus.CREATED)
public List<String> handleFileUpload(@RequestParam("files") MultipartFile[] files, String dir) {
//獲取項目當(dāng)前路徑
String projectFolder = System.getProperty("user.dir");
List<String> publicPathList = Lists.newArrayList();
for (MultipartFile file : files) {
//根據(jù)需求提供上傳路徑
String publicPath = "/upload/" + dir + "/" + file.getOriginalFilename();
File realFile = new File(projectFolder + publicPath);
file.transferTo(realFile);
publicPathList.add(publicPath);
}
return publicPathList;
}
html代碼:
<form action="/files" method="post" encType="multipart/form-data">
<!--注意accept屬性不要寫成*/*,會卡成翔,根據(jù)需求寫對應(yīng)的mime橙喘,別偷懶-->
<input type="file" name="files" multiple="multiple" accept="image/jpg,image/jpeg,image/png" />
<!--和文件一起提交別的參數(shù)-->
<input type="hidden" name="dir" value="avatar" />
</form>
文件處理 :
可以利用MultipartFile的getInputStream方法對文件進一步處理嘿架,舉個栗子,圖片壓縮:
//使用阿里的圖片處理庫:SimpleImage
private void scale(InputStream inputStream, FileOutputStream outputStream) throws SimpleImageException{
//這里默認(rèn)最大寬度1024,最大高度1024了慎式,可根據(jù)需求做成參數(shù)
ScaleParameter scaleParam = new ScaleParameter(1024,1024);
WriteParameter writeParam = new WriteParameter();
ImageRender rr = new ReadRender(inputStream);
ImageRender sr = new ScaleRender(rr, scaleParam);
ImageRender wr = null;
try {
wr = new WriteRender(sr, outputStream, ImageFormat.JPEG, writeParam);
wr.render();
} catch (SimpleImageException e) {
throw e;
} finally {
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
try {
if (wr != null) {
wr.dispose();
}
} catch (SimpleImageException e) {
// ignore ...
}
}
}
調(diào)用
scale(file.getInputStream(), new FileOutputStream(realFile));
踩坑
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>simpleimage</artifactId>
<version>1.2.3</version>
<!--使用spring boot時會和默認(rèn)引入的log4j-over-slf4j沖突终佛,需要干掉-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--SimpleImage依賴的javax.media.jai.core在官方的maven倉庫中并沒有,需要引用spring提供的-->
<dependency>
<groupId>javax.media.jai</groupId>
<artifactId>com.springsource.javax.media.jai.core</artifactId>
<version>1.1.3</version>
</dependency>
代碼組織:
建議將文件上傳處理部分抽出來翔忽,如:
FileService //文件處理接口
LocalFileServiceImpl //本地存儲文件處理實現(xiàn)
QiniuFileServiceImpl //七牛云存儲文件處理實現(xiàn)
上傳路徑和可訪問路徑可放到配置文件中英融,貼下spring-boot環(huán)境完整本地文件處理實現(xiàn)供參考:
LocalFileServiceImpl
@Service
public class LocalFileServiceImpl implements FileService {
@Resource
private UploadProperties uploadProperties;
@Override
public String upload(MultipartFile file, String dir, int maxWidth, int maxHeight) throws Exception {
String projectFolder = System.getProperty("user.dir");
String folderAndName = getFileUriGeneratedPart(file, dir);
String path = projectFolder + uploadProperties.getPath() + folderAndName;
File realFile = new File(path);
if(!realFile.getParentFile().exists()) {
if(!realFile.getParentFile().mkdirs()) {
throw new Exception("創(chuàng)建文件上傳目錄失敗");
}
}
try {
scale(file.getInputStream(), new FileOutputStream(realFile), maxWidth, maxHeight);
} catch (Exception e) {
throw new Exception(e.getMessage());
}
return uploadProperties.getPublicPath() + folderAndName;
}
private String getFileUriGeneratedPart(MultipartFile file, String dir) {
return "/" + dir + "/"+ genRandomString(16) +
"." + getExtensionName(file.getOriginalFilename());
}
//縮放用戶上傳圖片,減小寬帶占用
private void scale(InputStream inputStream, FileOutputStream outputStream, int maxWidth, int maxHeight) throws SimpleImageException{
ScaleParameter scaleParam = new ScaleParameter(maxWidth, maxHeight);
WriteParameter writeParam = new WriteParameter();
ImageRender rr = new ReadRender(inputStream);
ImageRender sr = new ScaleRender(rr, scaleParam);
ImageRender wr = null;
try {
wr = new WriteRender(sr, outputStream, ImageFormat.JPEG, writeParam);
wr.render();
} catch (SimpleImageException e) {
throw e;
} finally {
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
try {
if (wr != null) {
wr.dispose();
}
} catch (SimpleImageException e) {
// ignore ...
}
}
}
private static String getExtensionName(String filename) {
if (StringUtils.isNotBlank(filename)) {
int dot = filename.lastIndexOf('.');
if ((dot >-1) && (dot < (filename.length() - 1))) {
return filename.substring(dot + 1).toLowerCase();
}
}
return filename;
}
private static String genRandomString(int length) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
}
以上代碼移除了自定義的異常類
UploadProperties
@Component
@ConfigurationProperties("custom.upload")
public class UploadProperties {
private String path;
private String publicPath;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getPublicPath() {
return publicPath;
}
public void setPublicPath(String publicPath) {
this.publicPath = publicPath;
}
}
spring boot配置 application-local.yml
custom.upload:
path: /src/upload
public-path: /upload