zoukankan      html  css  js  c++  java
  • spring boot 文件上传工具类(bug 已修改)

    以前的文件上传都是之前前辈写的,现在自己来写一个,大家可以看看,有什么问题可以在评论中提出来。

    写的这个文件上传是在spring boot 2.0中测试的,测试了,可以正常上传,下面贴代码

    第一步:引入依赖 

    这里我用的是maven构建项目,spring boot 的相关pom我就不贴了,我这里贴我额外引入的。

    <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(具体路径,根据自己项目进行修改)

    # 自定义 属性文件,可使用 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));
        }
    
    }
  • 相关阅读:
    【笔记】算法图解
    redis两个主同时挂
    redis有间隔的kill 两个主:
    数据中心机房燃气分布式能源系统的作用是什么?
    C# DEBUG 调试信息打印及输出详解
    C# DEBUG 调试信息打印及输出详解
    C# DEBUG 调试信息打印及输出详解
    C# DEBUG 调试信息打印及输出详解
    多态中的题目分析题
    多态中的题目分析题
  • 原文地址:https://www.cnblogs.com/lixingwu/p/9864141.html
Copyright © 2011-2022 走看看