spring boot 文件上傳工具類(bug 已修改)

之前的文件上傳都是以前前輩寫的,如今本身來寫一個,你們能夠看看,有什麼問題能夠在評論中提出來。

寫的這個文件上傳是在spring boot 2.0中測試的,測試了,能夠正常上傳,下面貼代碼html

 

第一步:引入依賴 

這裏我用的是maven構建項目,spring boot 的相關pom我就不貼了,我這裏貼我額外引入的。java

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<!-- Apache Commons FileUpload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
<!-- Apache Commons IO  -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
<!-- thumbnailator 圖片壓縮工具 -->
<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.8</version>
</dependency>

 

第二步:編寫上傳返回結果實體 FileResult.java

import lombok.Data;

/**
 * 文件上傳返回的數據實體
 *
 * @author lixingwu
 */
@Data
public class FileResult {
// 文件名
private String fileName;
   // 擴展名
private String extName;
   // 文件大小,字節
private Long fileSize;
   // 文件存儲在服務器的相對地址
private String serverPath; }

 

第三步:編寫 PropertiesUtils.java 和 custom.properties

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 讀取properties文件
 *
 * @author lixingwu
 */
public class PropertiesUtils {
    private Properties properties;
    private static PropertiesUtils propertiesUtils = new PropertiesUtils();

    /**
     * 私有構造,禁止直接建立
     */
    private PropertiesUtils() {
        properties = new Properties();
        InputStream in = PropertiesUtils.class.getClassLoader()
                .getResourceAsStream("custom.properties");
        try {
            properties.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 獲取單例
     *
     * @return PropertiesUtils
     */
    public static PropertiesUtils getInstance() {
        if (propertiesUtils == null) {
            propertiesUtils = new PropertiesUtils();
        }
        return propertiesUtils;
    }

    /**
     * 根據屬性名讀取值
     *
     * @param name 名稱
     */
    public Object getProperty(String name) {
        return properties.getProperty(name);
    }


    /*************************************************************************/
    /*****************************讀取屬性,封裝字段**************************/
    /*************************************************************************/

    /**
     * 是否調試模式
     */
    public Boolean isDebug() {
        return "true".equals(properties.getProperty("isDebug"));
    }

    public String getAttachmentServer() {
        return properties.getProperty("attachmentServer");
    }

    public String getAttachmentPath() {
        return properties.getProperty("attachmentPath");
    }

    public String getAttachmentGainPpath() {
        return properties.getProperty("attachmentGainPath");
    }

    public static void main(String[] args) {
        PropertiesUtils pro = PropertiesUtils.getInstance();
        String value = String.valueOf(pro.getProperty("custom.properties.name").toString());
        System.out.println(value);
    }
}

 

 custom.properties(具體路徑,根據本身項目進行修改)web

# 自定義 屬性文件,可以使用 PropertiesUtils.java 來讀取
custom.properties.name=custom.properties
isDebug=true

#附件地址
attachmentServer=www.baidu.con/static

#服務器靜態文件地址 attachmentPath=/var/www/html #服務器存儲文件的地址
attachmentGainPath
=/var/www/html/upload

 

 

第四步:編寫 FileuploadUtil.java

package com.zhwlt.logistics.utils;

import com.zhwlt.logistics.pojo.system.FileResult;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 文件上傳工具類(修改了bug 2019-0105)
 *
 * @author lixingwu
 */
public class FileuploadUtil {

    /**
     * 屬性配置
     */
    private static PropertiesUtils pro = PropertiesUtils.getInstance();

    /**
     * 方法描述:根據文件的絕對路徑建立一個文件對象.
     * 建立時間:2018-10-19 09:32:34
     *
     * @param filePath 文件的絕對路徑
     * @return 返回建立的這個文件對象
     * @author "lixingwu"
     */
    public static File createFile(String filePath) throws IOException {
        // 獲取文件的完整目錄
        String fileDir = FilenameUtils.getFullPath(filePath);
        // 判斷目錄是否存在,不存在就建立一個目錄
        File file = new File(fileDir);
        if (!file.isDirectory()) {
            //建立失敗返回null
            if (!file.mkdirs()) {
                throw new IOException("文件目錄建立失敗...");
            }
        }
        // 判斷這個文件是否存在,不存在就建立
        file = new File(filePath);
        if (!file.exists()) {
            if (!file.createNewFile()) {
                throw new IOException("目標文件建立失敗...");
            }
        }
        return file;
    }

    /**
     * 方法描述:判斷extension中是否存在extName
     * 建立時間:2018-10-20 20:46:18
     *
     * @param extension 使用逗號隔開的字符串,精確匹配例如:txt,jpg,png,zip
     * @param extName   文件的後綴名
     * @author "lixingwu"
     */
    private static void isContains(String extension, String extName) {
        if (StringUtils.isNotEmpty(extension)) {
            // 切割文件擴展名
            String[] exts = StringUtils.split(extension, ",");
            if (ArrayUtils.isNotEmpty(exts)) {
                assert exts != null;
                List<String> extList = Arrays.asList(exts);
                //判斷
                if (!extList.contains(extName)) {
                    throw new RuntimeException("上傳文件的類型只能是:" + extension);
                }
            } else {
                // 判斷文件的後綴名是否爲extension
                if (!extension.equalsIgnoreCase(extName)) {
                    throw new RuntimeException("上傳文件的類型只能是:" + extension);
                }
            }
        }
    }

    /**
     * 方法描述:處理上傳的圖片
     * 建立時間:2018-10-20 20:46:18
     *
     * @param serverPath 圖片的絕對路徑
     * @param childFile  子文件夾
     * @param extName    文件的後綴
     * @author "lixingwu"
     */
    private static String thumbnails(String serverPath, String childFile, String extName)
            throws IOException {
        // 壓縮後的相對路徑文件名
        String toFilePath = getDestPath(childFile, extName);

        // scale:圖片縮放比例
        // outputQuality:圖片壓縮比例
        // toFile:圖片位置
        // outputFormat:文件輸出後綴名
        // Thumbnails 若是用來壓縮 png 格式的文件,會越壓越大,
        // 得把png格式的圖片轉換爲jpg格式
        if ("png".equalsIgnoreCase(extName)) {
            // 因爲outputFormat會自動在路徑後加上後綴名,因此移除之前的後綴名
            String removeExtensionFilePath = FilenameUtils.removeExtension(toFilePath);
            Thumbnails.of(serverPath).scale(1f)
                    .outputQuality(0.5f)
                    .outputFormat("jpg")
                    .toFile(getServerPath(removeExtensionFilePath));
            toFilePath = removeExtensionFilePath + ".jpg";
        } else {
            Thumbnails.of(serverPath).scale(1f).outputQuality(0.5f)
                    .toFile(getServerPath(toFilePath));
        }

        // 刪除被壓縮的文件
        FileUtils.forceDelete(new File(serverPath));

        return toFilePath;
    }

    /**
     * 方法描述:生成文件文件名
     * 建立時間:2018-10-20 20:46:18
     *
     * @param childFile 子目錄
     * @param extName   後綴名
     * @author "lixingwu"
     */
    private static String getDestPath(String childFile, String extName) {
        //規則:  子目錄/年月日_隨機數.後綴名
        String sb = childFile + "/"
                + DateUtil.formatDate(new Date(), DateUtil.DATE_FORMAT_SHORT)
                + "_" + Tools.getRandom()
                + "." + extName;
        return sb;
    }

    /**
     * 方法描述:生成文件在的實際的路徑
     * 建立時間:2018-10-20 20:46:18
     *
     * @param destPath 文件的相對路徑
     * @author "lixingwu"
     */
    private static String getServerPath(String destPath) {
        // 文件分隔符轉化爲當前系統的格式
        return FilenameUtils.separatorsToSystem(pro.getAttachmentGainPpath() + destPath);
    }

    /**
     * 方法描述:上傳文件.
     * 建立時間:2018-10-19 13:09:19
     *
     * @param multipartFile 上傳的文件對象,必傳
     * @param childFile     上傳的父目錄,爲空直接上傳到指定目錄 (會在指定的目錄下新建該目錄,例如:/user/1023)
     * @param extension     容許上傳的文件後綴名,爲空不限定上傳的文件類型 (使用逗號隔開的字符串,精確匹配例如:txt,jpg,png,zip)
     * @param isImage       上傳的是不是圖片,若是是就會進行圖片壓縮;若是不但願圖片被壓縮,則傳false,讓其以文件的形式來保存
     * @return the file result
     * @throws IOException 異常信息應返回
     * @author "lixingwu"
     */
    private static FileResult saveFile(MultipartFile multipartFile, String childFile, String extension, Boolean isImage) throws IOException {
        if (null == multipartFile || multipartFile.isEmpty()) {
            throw new IOException("上傳的文件對象不存在...");
        }
        // 文件名
        String fileName = multipartFile.getOriginalFilename();
        // 文件後綴名
        String extName = FilenameUtils.getExtension(fileName);
        if (StringUtils.isEmpty(extName)) {
            throw new RuntimeException("文件類型未定義不能上傳...");
        }
        // 判斷文件的後綴名是否符合規則
        isContains(extension, extName);
        // 建立目標文件的名稱,規則請看destPath方法
        String destPath = getDestPath(childFile, extName);
        // 文件的實際路徑
        String serverPath = getServerPath(destPath);
        // 建立文件
        File destFile = createFile(serverPath);
        // 保存文件
        multipartFile.transferTo(destFile);

        // 拼裝返回的數據
        FileResult result = new FileResult();
        //若是是圖片,就進行圖片處理
        if (BooleanUtils.isTrue(isImage)) {
            // 圖片處理
            String toFilePath = thumbnails(serverPath, childFile, extName);
            // 獲得處理後的圖片文件對象
            File file = new File(getServerPath(toFilePath));
            // 壓縮後的文件後綴名
            String extExtName = FilenameUtils.getExtension(toFilePath);
            // 源文件=源文件名.壓縮後的後綴名
            String extFileName = FilenameUtils.getBaseName(fileName) + "." + FilenameUtils.getExtension(toFilePath);
            result.setFileSize(file.length());
            result.setServerPath(toFilePath);
            result.setFileName(extFileName);
            result.setExtName(extExtName);
        } else {
            result.setFileSize(multipartFile.getSize());
            result.setFileName(fileName);
            result.setExtName(extName);
            result.setServerPath(destPath);
        }
        return result;
    }

    /**
     * 方法描述:上傳文件.
     * 建立時間:2018-10-19 13:09:19
     *
     * @param multipartFile 上傳的文件對象,必傳
     * @param childFile     上傳的父目錄,爲空直接上傳到指定目錄 (會在指定的目錄下新建該目錄,例如:/user/1023)
     * @param extension     容許上傳的文件後綴名,爲空不限定上傳的文件類型 (使用逗號隔開的字符串,精確匹配例如:txt,jpg,png,zip)
     * @return the file result
     * @throws IOException 異常信息應返回
     * @author "lixingwu"
     */
    public static FileResult saveFile(MultipartFile multipartFile, String childFile, String extension) throws IOException {
        return saveFile(multipartFile, childFile, extension, false);
    }

    /**
     * 方法描述:上傳圖片.
     * 建立時間:2018-10-19 13:09:19
     *
     * @param multipartFile 上傳的文件對象,必傳
     * @param childFile     上傳的父目錄,爲空直接上傳到指定目錄 (會在指定的目錄下新建該目錄,例如:/user/1023)
     * @param extension     容許上傳的文件後綴名,爲空不限定上傳的文件類型 (使用逗號隔開的字符串,精確匹配例如:txt,jpg,png,zip)
     * @return the file result
     * @throws IOException 異常信息應返回
     * @author "lixingwu"
     */
    public static FileResult saveImage(MultipartFile multipartFile, String childFile, String extension) throws IOException {
        return saveFile(multipartFile, childFile, extension, true);
    }

}

 

 

第五步:編寫 UploadCtl.java (測試可用 Postman)

package com.zhwlt.logistics.controller.system;

import com.zhwlt.logistics.controller.base.BaseController;
import com.zhwlt.logistics.pojo.system.CommonResult;
import com.zhwlt.logistics.utils.FileuploadUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * 上傳文件
 *
 * @author lixingwu
 */
@RestController
@RequestMapping("/system")
@Api(description = "上傳文件類", tags = {"UploadCtl"})
public class UploadCtl extends BaseController{

    /**
     * 方法描述:文件上傳,圖片也可使用,可是圖片不會被壓縮.
     * 建立時間:2018-10-19 14:10:32
     *
     * @param childFile 上傳的父目錄
     * @param extension 容許上傳的文件後綴名
     * @author "lixingwu"
     */
    @ApiOperation(value = "文件上傳", notes = "圖片也可使用,可是圖片不會被壓縮")
    @PostMapping("/uploadFile")
    public CommonResult uploadFile(
            MultipartFile multipart,
            @RequestParam(value = "childFile", required = false, defaultValue = "") String childFile,
            @RequestParam(value = "extension", required = false, defaultValue = "") String extension
    ) throws IOException {
        return resultDataWrapper(FileuploadUtil.saveFile(multipart, childFile, extension));
    }

    /**
     * 方法描述:圖片上傳,只能給圖片使用,其餘文件調用會異常.
     * 建立時間:2018-10-19 14:10:32
     *
     * @param childFile 上傳的父目錄
     * @param extension 容許上傳的文件後綴名
     * @author "lixingwu"
     */
    @ApiOperation(value = "圖片上傳", notes = "只能給圖片使用,其餘文件調用會異常")
    @PostMapping("/uploadImage")
    public CommonResult uploadImage(
            MultipartFile multipart,
            @RequestParam(value = "childFile", required = false, defaultValue = "") String childFile,
            @RequestParam(value = "extension", required = false, defaultValue = "") String extension
    ) throws IOException {
        return resultDataWrapper(FileuploadUtil.saveImage(multipart, childFile, extension));
    }

}
相關文章
相關標籤/搜索