xm
2024-06-14 722af26bc6fec32bb289b1df51a9016a4935610f
提交 | 用户 | 时间
722af2 1 package com.dl.common.utils.file;
X 2
3 import com.dl.common.config.DLConfig;
4 import com.dl.common.constant.Constants;
5 import com.dl.common.exception.file.FileNameLengthLimitExceededException;
6 import com.dl.common.exception.file.FileSizeLimitExceededException;
7 import com.dl.common.exception.file.InvalidExtensionException;
8 import com.dl.common.utils.DateUtils;
9 import com.dl.common.utils.Seq;
10 import com.dl.common.utils.StringUtils;
11 import org.apache.commons.io.FilenameUtils;
12 import org.springframework.web.multipart.MultipartFile;
13
14 import java.io.File;
15 import java.io.IOException;
16 import java.nio.file.Paths;
17 import java.util.Objects;
18
19 /**
20  * 文件上传工具类
21  *
22  * @author dl
23  */
24 public class FileUploadUtils
25 {
26     /**
27      * 默认大小 50M
28      */
29     public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
30
31     /**
32      * 默认的文件名最大长度 100
33      */
34     public static final int DEFAULT_FILE_NAME_LENGTH = 100;
35
36     /**
37      * 默认上传的地址
38      */
39     private static String defaultBaseDir = DLConfig.getProfile();
40
41     public static void setDefaultBaseDir(String defaultBaseDir)
42     {
43         FileUploadUtils.defaultBaseDir = defaultBaseDir;
44     }
45
46     public static String getDefaultBaseDir()
47     {
48         return defaultBaseDir;
49     }
50
51     /**
52      * 以默认配置进行文件上传
53      *
54      * @param file 上传的文件
55      * @return 文件名称
56      * @throws Exception
57      */
58     public static final String upload(MultipartFile file) throws IOException
59     {
60         try
61         {
62             return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
63         }
64         catch (Exception e)
65         {
66             throw new IOException(e.getMessage(), e);
67         }
68     }
69
70     /**
71      * 根据文件路径上传
72      *
73      * @param baseDir 相对应用的基目录
74      * @param file 上传的文件
75      * @return 文件名称
76      * @throws IOException
77      */
78     public static final String upload(String baseDir, MultipartFile file) throws IOException
79     {
80         try
81         {
82             return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
83         }
84         catch (Exception e)
85         {
86             throw new IOException(e.getMessage(), e);
87         }
88     }
89
90     /**
91      * 文件上传
92      *
93      * @param baseDir 相对应用的基目录
94      * @param file 上传的文件
95      * @param allowedExtension 上传文件类型
96      * @return 返回上传成功的文件名
97      * @throws FileSizeLimitExceededException 如果超出最大大小
98      * @throws FileNameLengthLimitExceededException 文件名太长
99      * @throws IOException 比如读写文件出错时
100      * @throws InvalidExtensionException 文件校验异常
101      */
102     public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
103             throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
104             InvalidExtensionException
105     {
106         int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
107         if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
108         {
109             throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
110         }
111
112         assertAllowed(file, allowedExtension);
113
114         String fileName = extractFilename(file);
115
116         String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
117         file.transferTo(Paths.get(absPath));
118         return getPathFileName(baseDir, fileName);
119     }
120
121     /**
122      * 编码文件名
123      */
124     public static final String extractFilename(MultipartFile file)
125     {
126         return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
127                 FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
128     }
129
130     public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
131     {
132         File desc = new File(uploadDir + File.separator + fileName);
133
134         if (!desc.exists())
135         {
136             if (!desc.getParentFile().exists())
137             {
138                 desc.getParentFile().mkdirs();
139             }
140         }
141         return desc;
142     }
143
144     public static final String getPathFileName(String uploadDir, String fileName) throws IOException
145     {
146         int dirLastIndex = DLConfig.getProfile().length() + 1;
147         String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
148         return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
149     }
150
151     /**
152      * 文件大小校验
153      *
154      * @param file 上传的文件
155      * @return
156      * @throws FileSizeLimitExceededException 如果超出最大大小
157      * @throws InvalidExtensionException
158      */
159     public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
160             throws FileSizeLimitExceededException, InvalidExtensionException
161     {
162         long size = file.getSize();
163         if (size > DEFAULT_MAX_SIZE)
164         {
165             throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
166         }
167
168         String fileName = file.getOriginalFilename();
169         String extension = getExtension(file);
170         if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
171         {
172             if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
173             {
174                 throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
175                         fileName);
176             }
177             else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
178             {
179                 throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
180                         fileName);
181             }
182             else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
183             {
184                 throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
185                         fileName);
186             }
187             else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
188             {
189                 throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
190                         fileName);
191             }
192             else
193             {
194                 throw new InvalidExtensionException(allowedExtension, extension, fileName);
195             }
196         }
197     }
198
199     /**
200      * 判断MIME类型是否是允许的MIME类型
201      *
202      * @param extension
203      * @param allowedExtension
204      * @return
205      */
206     public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
207     {
208         for (String str : allowedExtension)
209         {
210             if (str.equalsIgnoreCase(extension))
211             {
212                 return true;
213             }
214         }
215         return false;
216     }
217
218     /**
219      * 获取文件名的后缀
220      *
221      * @param file 表单文件
222      * @return 后缀名
223      */
224     public static final String getExtension(MultipartFile file)
225     {
226         String extension = FilenameUtils.getExtension(file.getOriginalFilename());
227         if (StringUtils.isEmpty(extension))
228         {
229             extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
230         }
231         return extension;
232     }
233 }