spring mvc多文件上傳

適用 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{
    //這里默認最大寬度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時會和默認引入的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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容