FileUploadUtils.java 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package com.xunmei.file.utils;
  2. import cn.hutool.core.codec.Base64;
  3. import cn.hutool.core.io.FileUtil;
  4. import com.xunmei.common.core.exception.file.FileException;
  5. import com.xunmei.common.core.exception.file.FileNameLengthLimitExceededException;
  6. import com.xunmei.common.core.exception.file.FileSizeLimitExceededException;
  7. import com.xunmei.common.core.exception.file.InvalidExtensionException;
  8. import com.xunmei.common.core.utils.DateUtils;
  9. import com.xunmei.common.core.utils.StringUtils;
  10. import com.xunmei.common.core.utils.file.FileTypeUtils;
  11. import com.xunmei.common.core.utils.file.MimeTypeUtils;
  12. import com.xunmei.common.core.utils.uuid.Seq;
  13. import com.xunmei.file.vo.FileBase64Vo;
  14. import org.apache.commons.lang3.StringEscapeUtils;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import org.springframework.web.multipart.MultipartFile;
  18. import java.io.File;
  19. import java.io.IOException;
  20. import java.nio.file.Paths;
  21. import java.util.Objects;
  22. /**
  23. * 文件上传工具类
  24. *
  25. * @author xunmei
  26. */
  27. public class FileUploadUtils
  28. {
  29. private static final Logger log = LoggerFactory.getLogger(FileUploadUtils.class);
  30. /**
  31. * 默认大小 50M
  32. */
  33. public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
  34. /**
  35. * 默认的文件名最大长度 100
  36. */
  37. public static final int DEFAULT_FILE_NAME_LENGTH = 100;
  38. /**
  39. * 根据文件路径上传
  40. *
  41. * @param baseDir 相对应用的基目录
  42. * @param file 上传的文件
  43. * @return 文件名称
  44. * @throws IOException
  45. */
  46. public static final String upload(String baseDir, MultipartFile file) throws IOException
  47. {
  48. try
  49. {
  50. return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION.toArray(new String[0]));
  51. }
  52. catch (FileException fe)
  53. {
  54. throw new IOException(fe.getDefaultMessage(), fe);
  55. }
  56. catch (Exception e)
  57. {
  58. throw new IOException(e.getMessage(), e);
  59. }
  60. }
  61. public static final String upload(String baseDir, MultipartFile file,String busType) throws IOException
  62. {
  63. try
  64. {
  65. String upload = upload(baseDir + File.separator + busType, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION.toArray(new String[0]));
  66. return File.separator + busType + upload;
  67. }
  68. catch (FileException fe)
  69. {
  70. throw new IOException(fe.getDefaultMessage(), fe);
  71. }
  72. catch (Exception e)
  73. {
  74. throw new IOException(e.getMessage(), e);
  75. }
  76. }
  77. /**
  78. * 文件上传
  79. *
  80. * @param baseDir 相对应用的基目录
  81. * @param file 上传的文件
  82. * @param allowedExtension 上传文件类型
  83. * @return 返回上传成功的文件名
  84. * @throws FileSizeLimitExceededException 如果超出最大大小
  85. * @throws FileNameLengthLimitExceededException 文件名太长
  86. * @throws IOException 比如读写文件出错时
  87. * @throws InvalidExtensionException 文件校验异常
  88. */
  89. public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
  90. throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
  91. InvalidExtensionException
  92. {
  93. int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
  94. if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
  95. {
  96. throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
  97. }
  98. assertAllowed(file, allowedExtension);
  99. String fileName = extractFilename(file);
  100. String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
  101. file.transferTo(Paths.get(absPath));
  102. return getPathFileName(fileName);
  103. }
  104. public static final String uploadBase64(String baseDir, FileBase64Vo file)
  105. throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
  106. InvalidExtensionException{
  107. byte[] decode = Base64.decode(file.getContent());
  108. String extension = file.getExtension();
  109. if(StringUtils.isEmpty(extension) || "null".equals(extension))
  110. {
  111. extension="png";
  112. }
  113. String fileName = extractFilename(extension);
  114. File absoluteFile = getAbsoluteFile(baseDir, fileName);
  115. FileUtil.writeBytes(decode,absoluteFile);
  116. return getPathFileName(fileName);
  117. }
  118. /**
  119. * 编码文件名
  120. */
  121. public static final String extractFilename(MultipartFile file)
  122. {
  123. return StringUtils.format("{}/{}.{}", DateUtils.datePath(), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file));
  124. }
  125. /**
  126. * 编码文件名
  127. */
  128. public static final String extractFilename(String fileLast)
  129. {
  130. return StringUtils.format("{}/{}.{}", DateUtils.datePath(), Seq.getId(Seq.uploadSeqType), fileLast);
  131. }
  132. public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
  133. {
  134. File desc = new File(uploadDir + File.separator + fileName);
  135. String path = StringEscapeUtils.escapeEcmaScript(desc.getAbsolutePath());
  136. String file = StringEscapeUtils.escapeEcmaScript(desc.getParentFile().getName());
  137. log.info("当前上传文件地址:{}",path);
  138. if (!desc.exists())
  139. {
  140. if (!desc.getParentFile().exists())
  141. {
  142. log.info("创建文件夹:{}",file);
  143. desc.getParentFile().mkdirs();
  144. }
  145. }
  146. return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
  147. }
  148. private static final String getPathFileName(String fileName) throws IOException
  149. {
  150. String pathFileName = "/" + fileName;
  151. return pathFileName;
  152. }
  153. /**
  154. * 文件大小校验
  155. *
  156. * @param file 上传的文件
  157. * @throws FileSizeLimitExceededException 如果超出最大大小
  158. * @throws InvalidExtensionException 文件校验异常
  159. */
  160. public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
  161. throws FileSizeLimitExceededException, InvalidExtensionException
  162. {
  163. long size = file.getSize();
  164. if (size > DEFAULT_MAX_SIZE)
  165. {
  166. throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
  167. }
  168. String fileName = file.getOriginalFilename();
  169. String extension = FileTypeUtils.getExtension(file);
  170. if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
  171. {
  172. if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION.toArray(new String[0]))
  173. {
  174. throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
  175. fileName);
  176. }
  177. else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION.toArray(new String[0]))
  178. {
  179. throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
  180. fileName);
  181. }
  182. else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION.toArray(new String[0]))
  183. {
  184. throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
  185. fileName);
  186. }
  187. else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION.toArray(new String[0]))
  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. * 判断MIME类型是否是允许的MIME类型
  200. *
  201. * @param extension 上传文件类型
  202. * @param allowedExtension 允许上传文件类型
  203. * @return true/false
  204. */
  205. public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
  206. {
  207. for (String str : allowedExtension)
  208. {
  209. if (str.equalsIgnoreCase(extension))
  210. {
  211. return true;
  212. }
  213. }
  214. return false;
  215. }
  216. }