What is distributed file
Distributed file system refers to the physical storage resources managed by the file system, which are not necessarily directly connected to the local node, but connected to the node through the computer network.
Why use distributed files
How to meet the demand of massive data storage system in the Internet era? Simply increasing the number of hard disks can not meet our requirements, because the transmission speed of hard disks is limited, but the data is growing rapidly. In addition, we need to do a good job in data backup and data security
nacos service configuration file (bootstrap.yml)
# Tomcat server: port: 9300 # Spring spring: servlet: multipart: maxFileSize: 1024MB maxRequestSize: 1024MB application: # apply name name: ******* profiles: # Environment configuration active: dev cloud: nacos: discovery: # Service registration address server-addr: 127.0.0.1:8848 config: # Configuration center address server-addr: 127.0.0.1:8848 # Configuration file format file-extension: yml # Shared configuration shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
nacos service profile
# Local file upload file: domain: http://127.0.0.1:9300 /** Example of file path (Windows configuration D:/guangzhou/uploadPath, Linux configuration / home/guangzhou/uploadPath)*/ path: D:/guangzhou/uploadPath /** Static resource matching path*/ prefix: /statics # Minio configuration minio: url: http://127.0.0.1:9000 accessKey: minioadmin secretKey: minioadmin bucketName: *****
pom.xml file
<!-- Minio --> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>${minio.version}</version> </dependency> <!-- Alibaba Fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> <!-- Apache Lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <!-- Commons Io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> <!-- Commons Fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> </dependency>
Upload unified portal
@RestController public class SysFileController { private static final Logger log = LoggerFactory.getLogger(SysFileController.class); @Autowired private ISysFileService sysFileService; /** After uploading successfully, the returned information is stored in the database and customized*/ @Autowired(required = false) private SysEnclosureSrevice sysEnclosureSrevice; /** * File upload request */ @PostMapping("upload") public R<SysEnclosure> upload(MultipartFile file) { try { //Original file name String fileOldName=file.getOriginalFilename(); // Upload and return access address SysEnclosure s = sysFileService.uploadFile(file); SysEnclosure sysEnclosure = new SysEnclosure(); sysEnclosure.setEnclosureNewName(FileUtils.getName(s.getEnclosureUrl())); sysEnclosure.setCreateTime(String.valueOf(new Date())); sysEnclosure.setEnclosureUrl(s.getEnclosureUrl()); sysEnclosure.setEnclosureOldName(fileOldName); sysEnclosure.setSuffix(s.getSuffix()); sysEnclosureSrevice.crateEnclosure(sysEnclosure); return R.ok(sysEnclosure); } catch (Exception e) { log.error("Failed to upload file", e); return R.fail(e.getMessage()); } }
Upload unified interface server
public interface ISysFileService { /** * File upload interface * * @param file Uploaded files * @return Access address * @throws Exception */ public SysEnclosure uploadFile(MultipartFile file) throws Exception; }
Local storage ServiceImpl
@Service public class LocalSysFileServiceImpl implements ISysFileService { private static final Logger log = LoggerFactory.getLogger(LocalSysFileServiceImpl.class); /** * Resource mapping path prefix */ @Value("${file.prefix}") public String localFilePrefix; /** * Domain name or local access address */ @Value("${file.domain}") public String domain; /** * The uploaded file is stored in the local root path */ @Value("${file.path}") private String localFilePath; /** * Local file upload interface * * @param file Uploaded files * @return Access address * @throws Exception */ @Override public SysEnclosure uploadFile(MultipartFile file) throws Exception { SysEnclosure sysEnclosure=new SysEnclosure(); String name = FileUploadUtils.upload(localFilePath, file); String url = domain + localFilePrefix + name; sysEnclosure.setEnclosureUrl(url); return sysEnclosure; }
Minio storage ServiceImpl
@Primary @Service public class MinioSysFileServiceImpl implements ISysFileService { @Autowired private MinioConfig minioConfig; @Autowired private MinioClient client; /** * Local file upload interface * * @param file Uploaded files * @return Access address * @throws Exception */ @Override public SysEnclosure uploadFile(MultipartFile file) throws Exception { SysEnclosure sysEnclosure=new SysEnclosure(); String fileName = FileUploadUtils.extractFilename(file); //Attachment suffix String extension = getExtension(file); PutObjectArgs args = PutObjectArgs.builder() .bucket(minioConfig.getBucketName()) .object(fileName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build(); client.putObject(args); sysEnclosure.setEnclosureUrl(minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName); sysEnclosure.setSuffix(extension); return sysEnclosure; }
Note that the following are tool classes
File upload tool class
public class FileUploadUtils { /** * Default size 1024M */ public static final long DEFAULT_MAX_SIZE = 1024 * 1024 * 1024; /** * The default file name has a maximum length of 100 */ public static final int DEFAULT_FILE_NAME_LENGTH = 1000; /** * Upload according to file path * * @param baseDir Base directory of relative application * @param file Uploaded files * @return File name * @throws IOException */ public static final String upload(String baseDir, MultipartFile file) throws IOException { try { return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); } catch (Exception e) { throw new IOException(e.getMessage(), e); } } /** * File upload * * @param baseDir Base directory of relative application * @param file Uploaded files * @param allowedExtension Upload file type * @return Returns the file name that was uploaded successfully * @throws FileSizeLimitExceededException If the maximum size is exceeded * @throws FileNameLengthLimitExceededException file name is too long * @throws IOException For example, when there is an error reading or writing a file * @throws InvalidExtensionException File verification exception */ public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, InvalidExtensionException { int fileNamelength = file.getOriginalFilename().length(); if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) { throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); } assertAllowed(file, allowedExtension); String fileName = extractFilename(file); File desc = getAbsoluteFile(baseDir, fileName); file.transferTo(desc); String pathFileName = getPathFileName(fileName); return pathFileName; } /** * Encoded file name */ public static final String extractFilename(MultipartFile file) { String extension = getExtension(file); String fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension; return fileName; } private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException { File desc = new File(uploadDir + File.separator + fileName); if (!desc.exists()) { if (!desc.getParentFile().exists()) { desc.getParentFile().mkdirs(); } } return desc.isAbsolute() ? desc : desc.getAbsoluteFile(); } private static final String getPathFileName(String fileName) throws IOException { String pathFileName = "/" + fileName; return pathFileName; } /** * File size verification * * @param file Uploaded files * @throws FileSizeLimitExceededException If the maximum size is exceeded * @throws InvalidExtensionException File verification exception */ public static final void assertAllowed(MultipartFile file, String[] allowedExtension) throws FileSizeLimitExceededException, InvalidExtensionException { long size = file.getSize(); if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) { throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); } String fileName = file.getOriginalFilename(); String extension = getExtension(file); if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) { if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) { throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, fileName); } else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) { throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, fileName); } else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) { throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, fileName); } else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) { throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, fileName); } else { throw new InvalidExtensionException(allowedExtension, extension, fileName); } } } /** * Determine whether the MIME type is an allowed MIME type * * @param extension Upload file type * @param allowedExtension File types allowed to upload * @return true/false */ public static final boolean isAllowedExtension(String extension, String[] allowedExtension) { for (String str : allowedExtension) { if (str.equalsIgnoreCase(extension)) { return true; } } return false; } /** * Gets the suffix of the file name * * @param file Form file * @return Suffix */ public static final String getExtension(MultipartFile file) { String extension = FilenameUtils.getExtension(file.getOriginalFilename()); if (StringUtils.isEmpty(extension)) { extension = MimeTypeUtils.getExtension(file.getContentType()); } return extension; } }
Media type tool class
/** * Media type tool class * * @author */ public class MimeTypeUtils { public static final String IMAGE_PNG = "image/png"; public static final String IMAGE_JPG = "image/jpg"; public static final String IMAGE_JPEG = "image/jpeg"; public static final String IMAGE_BMP = "image/bmp"; public static final String IMAGE_GIF = "image/gif"; public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; public static final String[] FLASH_EXTENSION = { "swf", "flv" }; public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", "asf", "rm", "rmvb" }; public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" }; public static final String[] DEFAULT_ALLOWED_EXTENSION = { // picture "bmp", "gif", "jpg", "jpeg", "png", // word excel powerpoint "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", // Compressed file "rar", "zip", "gz", "bz2", // Video format "mp4", "avi", "rmvb", // pdf "pdf" }; public static String getExtension(String prefix) { switch (prefix) { case IMAGE_PNG: return "png"; case IMAGE_JPG: return "jpg"; case IMAGE_JPEG: return "jpeg"; case IMAGE_BMP: return "bmp"; case IMAGE_GIF: return "gif"; default: return ""; } } }
ID generator tool class
/** * ID Generator tool class * * @author */ public class IdUtils { /** * Get random UUID * * @return Random UUID */ public static String randomUUID() { return UUID.randomUUID().toString(); } /** * Simplified UUID with horizontal lines removed * * @return Simplified UUID with horizontal lines removed */ public static String simpleUUID() { return UUID.randomUUID().toString(true); } /** * Obtain the random UUID, and use ThreadLocalRandom with better performance to generate the UUID * * @return Random UUID */ public static String fastUUID() { return UUID.fastUUID().toString(); } /** * The simplified UUID removes horizontal lines and uses ThreadLocalRandom with better performance to generate UUIDs * * @return Simplified UUID with horizontal lines removed */ public static String fastSimpleUUID() { return UUID.fastUUID().toString(true); } }
Time tool class
/** * Time tool class * * @author */ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public static String YYYY = "yyyy"; public static String YYYY_MM = "yyyy-MM"; public static String YYYY_MM_DD = "yyyy-MM-dd"; public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; /** * Get the current Date type Date * * @return Date() current date */ public static Date getNowDate() { return new Date(); } /** * Gets the current date. The default format is yyyy mm DD * * @return String */ public static String getDate() { return dateTimeNow(YYYY_MM_DD); } public static final String getTime() { return dateTimeNow(YYYY_MM_DD_HH_MM_SS); } public static final String dateTimeNow() { return dateTimeNow(YYYYMMDDHHMMSS); } public static final String dateTimeNow(final String format) { return parseDateToStr(format, new Date()); } public static final String dateTime(final Date date) { return parseDateToStr(YYYY_MM_DD, date); } public static final String parseDateToStr(final String format, final Date date) { return new SimpleDateFormat(format).format(date); } public static final Date dateTime(final String format, final String ts) { try { return new SimpleDateFormat(format).parse(ts); } catch (ParseException e) { throw new RuntimeException(e); } } /** * Date path, i.e. year / month / day, e.g. 2018 / 08 / 08 */ public static final String datePath() { Date now = new Date(); return DateFormatUtils.format(now, "yyyy/MM/dd"); } /** * Date path, i.e. year / month / day, e.g. 201808 */ public static final String dateTime() { Date now = new Date(); return DateFormatUtils.format(now, "yyyyMMdd"); } /** * Convert date string to date format */ public static Date parseDate(Object str) { if (str == null) { return null; } try { return parseDate(str.toString(), parsePatterns); } catch (ParseException e) { return null; } } /** * Get server startup time */ public static Date getServerStartDate() { long time = ManagementFactory.getRuntimeMXBean().getStartTime(); return new Date(time); } /** * Calculate two time differences */ public static String getDatePoor(Date endDate, Date nowDate) { long nd = 1000 * 24 * 60 * 60; long nh = 1000 * 60 * 60; long nm = 1000 * 60; // long ns = 1000; // Gets the millisecond time difference between the two times long diff = endDate.getTime() - nowDate.getTime(); // How many days is the difference long day = diff / nd; // How many hours is the difference long hour = diff % nd / nh; // Calculate the difference in minutes long min = diff % nd % nh / nm; // Calculate the difference in seconds. / / the result is output // long sec = diff % nd % nh % nm / ns; return day + "day" + hour + "hour" + min + "minute"; } }
package com.ruoyi.common.core.utils; import java.util.Collection; import java.util.List; import java.util.Map; import org.springframework.util.AntPathMatcher; import com.ruoyi.common.core.text.StrFormatter; /** * String utility class * * @author */ public class StringUtils extends org.apache.commons.lang3.StringUtils { /** Empty string */ private static final String NULLSTR = ""; /** Underline */ private static final char SEPARATOR = '_'; /** * Get parameter is not null * * @param value defaultValue value to judge * @return value Return value */ public static <T> T nvl(T value, T defaultValue) { return value != null ? value : defaultValue; } /** * * Judge whether a Collection is empty, including List, Set and Queue * * @param coll Collection to judge * @return true: Null false: not null */ public static boolean isEmpty(Collection<?> coll) { return isNull(coll) || coll.isEmpty(); } /** * * Judge whether a Collection is not empty, including List, Set and Queue * * @param coll Collection to judge * @return true: Non null false: null */ public static boolean isNotEmpty(Collection<?> coll) { return !isEmpty(coll); } /** * * Determine whether an object array is empty * * @param objects Array of objects to judge ** @return true: Null false: not null */ public static boolean isEmpty(Object[] objects) { return isNull(objects) || (objects.length == 0); } /** * * Determine whether an object array is not empty * * @param objects Array of objects to judge * @return true: Non null false: null */ public static boolean isNotEmpty(Object[] objects) { return !isEmpty(objects); } /** * * Judge whether a Map is empty * * @param map Map to judge * @return true: Null false: not null */ public static boolean isEmpty(Map<?, ?> map) { return isNull(map) || map.isEmpty(); } /** * * Judge whether a Map is empty * * @param map Map to judge * @return true: Non null false: null */ public static boolean isNotEmpty(Map<?, ?> map) { return !isEmpty(map); } /** * * Determine whether a string is an empty string * * @param str String * @return true: Null false: not null */ public static boolean isEmpty(String str) { return isNull(str) || NULLSTR.equals(str.trim()); } /** * * Judge whether a string is non empty * * @param str String * @return true: Non empty string false: empty string */ public static boolean isNotEmpty(String str) { return !isEmpty(str); } /** * * Judge whether an object is empty * * @param object Object * @return true: Null false: not null */ public static boolean isNull(Object object) { return object == null; } /** * * Judge whether an object is not empty * * @param object Object * @return true: Non null false: null */ public static boolean isNotNull(Object object) { return !isNull(object); } /** * * Determine whether an object is an array type (array of Java basic types) * * @param object object * @return true: Is an array false: not an array */ public static boolean isArray(Object object) { return isNotNull(object) && object.getClass().isArray(); } /** * Go to space */ public static String trim(String str) { return (str == null ? "" : str.trim()); } /** * Intercept string * * @param str character string * @param start start * @return result */ public static String substring(final String str, int start) { if (str == null) { return NULLSTR; } if (start < 0) { start = str.length() + start; } if (start < 0) { start = 0; } if (start > str.length()) { return NULLSTR; } return str.substring(start); } /** * Intercept string * * @param str character string * @param start start * @param end end * @return result */ public static String substring(final String str, int start, int end) { if (str == null) { return NULLSTR; } if (end < 0) { end = str.length() + end; } if (start < 0) { start = str.length() + start; } if (end > str.length()) { end = str.length(); } if (start > end) { return NULLSTR; } if (start < 0) { start = 0; } if (end < 0) { end = 0; } return str.substring(start, end); } /** * Determine whether it is empty and not a blank character * * @param str value to judge * @return result */ public static boolean hasText(String str) { return (str != null && !str.isEmpty() && containsText(str)); } private static boolean containsText(CharSequence str) { int strLen = str.length(); for (int i = 0; i < strLen; i++) { if (!Character.isWhitespace(str.charAt(i))) { return true; } } return false; } /** * Formatted text, {} indicates placeholder < br > * This method simply replaces the placeholder {} with the parameter < br > in order * If you want to output {}, you can use \ \ escape {, and if you want to output \ before {}, you can use double escape character \ \ \ < br > * Example: < br > * Usually: format ("this is {} for {}", "a", "B") - > this is a for B < br > * Escape {}: format ("this is \ {} for {}", "a", "B") - > this is \ {} for a < br > * Escape \: format ("this is \ \ \ \ {} for {}", "a", "B") - > this is \ a for B < br > * * @param template Text template, the replaced part is represented by {} * @param params Parameter value * @return Formatted text */ public static String format(String template, Object... params) { if (isEmpty(params) || isEmpty(template)) { return template; } return StrFormatter.format(template, params); } /** * Hump to hump naming */ public static String toUnderScoreCase(String str) { if (str == null) { return null; } StringBuilder sb = new StringBuilder(); // Whether the leading character is capitalized boolean preCharIsUpperCase = true; // Whether the current character is capitalized boolean curreCharIsUpperCase = true; // Whether the next character is capitalized boolean nexteCharIsUpperCase = true; for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if (i > 0) { preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); } else { preCharIsUpperCase = false; } curreCharIsUpperCase = Character.isUpperCase(c); if (i < (str.length() - 1)) { nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); } if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) { sb.append(SEPARATOR); } else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) { sb.append(SEPARATOR); } sb.append(Character.toLowerCase(c)); } return sb.toString(); } /** * Whether to include string * * @param str Validation string * @param strs String group * @return Include return true */ public static boolean inStringIgnoreCase(String str, String... strs) { if (str != null && strs != null) { for (String s : strs) { if (str.equalsIgnoreCase(trim(s))) { return true; } } } return false; } /** * Converts an underlined uppercase named string to a hump. If the string named by the underscore uppercase method before conversion is empty, an empty string is returned. For example: Hello_ WORLD->HelloWorld * * @param name String named in uppercase with underscore before conversion * @return Converted hump named string */ public static String convertToCamelCase(String name) { StringBuilder result = new StringBuilder(); // Quick check if (name == null || name.isEmpty()) { // There is no need to convert return ""; } else if (!name.contains("_")) { // No underline, capitalize only the first letter return name.substring(0, 1).toUpperCase() + name.substring(1); } // Divide the original string with an underscore String[] camels = name.split("_"); for (String camel : camels) { // Skip underscores or double underscores at the beginning and end of the original string if (camel.isEmpty()) { continue; } // title case result.append(camel.substring(0, 1).toUpperCase()); result.append(camel.substring(1).toLowerCase()); } return result.toString(); } /** * Hump nomenclature e.g. user_ name->userName */ public static String toCamelCase(String s) { if (s == null) { return null; } s = s.toLowerCase(); StringBuilder sb = new StringBuilder(s.length()); boolean upperCase = false; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == SEPARATOR) { upperCase = true; } else if (upperCase) { sb.append(Character.toUpperCase(c)); upperCase = false; } else { sb.append(c); } } return sb.toString(); } /** * Finds whether the specified string matches any string in the specified string list * * @param str Specify string * @param strs Array of strings to check * @return Match */ public static boolean matches(String str, List<String> strs) { if (isEmpty(str) || isEmpty(strs)) { return false; } for (String pattern : strs) { if (isMatch(pattern, str)) { return true; } } return false; } /** * Determine whether the url is consistent with the rule configuration: * ? Represents a single character; * * Represents any string within a layer path, and cannot cross levels; * ** Represents the path of any layer; * * @param pattern Matching rules * @param url A matching url is required * @return */ public static boolean isMatch(String pattern, String url) { AntPathMatcher matcher = new AntPathMatcher(); return matcher.match(pattern, url); } @SuppressWarnings("unchecked") public static <T> T cast(Object obj) { return (T) obj; } } <-------------------------------Gorgeous split line---------------------> /** * String formatting * * @author */ public class StrFormatter { public static final String EMPTY_JSON = "{}"; public static final char C_BACKSLASH = '\\'; public static final char C_DELIM_START = '{'; public static final char C_DELIM_END = '}'; /** * Format string < br > * This method simply replaces the placeholder {} with the parameter < br > in order * If you want to output {}, you can use \ \ escape {, and if you want to output \ before {}, you can use double escape character \ \ \ < br > * Example: < br > * Usually: format ("this is {} for {}", "a", "B") - > this is a for B < br > * Escape {}: format ("this is \ {} for {}", "a", "B") - > this is \ {} for a < br > * Escape \: format ("this is \ \ \ \ {} for {}", "a", "B") - > this is \ a for B < br > * * @param strPattern String template * @param argArray parameter list * @return result */ public static String format(final String strPattern, final Object... argArray) { if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) { return strPattern; } final int strPatternLength = strPattern.length(); // Initialize the defined length for better performance StringBuilder sbuf = new StringBuilder(strPatternLength + 50); int handledPosition = 0; int delimIndex;// Placeholder location for (int argIndex = 0; argIndex < argArray.length; argIndex++) { delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); if (delimIndex == -1) { if (handledPosition == 0) { return strPattern; } else { // The rest of the string template no longer contains placeholders. The result will be returned after adding the rest sbuf.append(strPattern, handledPosition, strPatternLength); return sbuf.toString(); } } else { if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) { if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) { // There is an escape character before the escape character, and the placeholder is still valid sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(Convert.utf8Str(argArray[argIndex])); handledPosition = delimIndex + 2; } else { // Placeholder escaped argIndex--; sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(C_DELIM_START); handledPosition = delimIndex + 1; } } else { // Normal placeholder sbuf.append(strPattern, handledPosition, delimIndex); sbuf.append(Convert.utf8Str(argArray[argIndex])); handledPosition = delimIndex + 2; } } } // All characters after adding the last placeholder sbuf.append(strPattern, handledPosition, strPattern.length()); return sbuf.toString(); } }
Exception class
/** * File name size limit exception class * * @author */ public class FileSizeLimitExceededException extends FileException { private static final long serialVersionUID = 1L; public FileSizeLimitExceededException(long defaultMaxSize) { super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); } } <-------------------------------Gorgeous split line---------------------> /** * File information exception class * * @author */ public class FileException extends BaseException { private static final long serialVersionUID = 1L; public FileException(String code, Object[] args) { super("file", code, args, null); } } <-------------------------------Gorgeous split line---------------------> /** * Basic anomaly * * @author */ public class BaseException extends RuntimeException { private static final long serialVersionUID = 1L; /** * Module */ private String module; /** * Error code */ private String code; /** * Parameter corresponding to error code */ private Object[] args; /** * Error message */ private String defaultMessage; public BaseException(String module, String code, Object[] args, String defaultMessage) { this.module = module; this.code = code; this.args = args; this.defaultMessage = defaultMessage; } public BaseException(String module, String code, Object[] args) { this(module, code, args, null); } public BaseException(String module, String defaultMessage) { this(module, null, null, defaultMessage); } public BaseException(String code, Object[] args) { this(null, code, args, null); } public BaseException(String defaultMessage) { this(null, null, null, defaultMessage); } public String getModule() { return module; } public String getCode() { return code; } public Object[] getArgs() { return args; } public String getDefaultMessage() { return defaultMessage; } } <-------------------------------Gorgeous split line---------------------> /** * Basic anomaly * * @author */ public class BaseException extends RuntimeException { private static final long serialVersionUID = 1L; /** * Module */ private String module; /** * Error code */ private String code; /** * Parameter corresponding to error code */ private Object[] args; /** * Error message */ private String defaultMessage; public BaseException(String module, String code, Object[] args, String defaultMessage) { this.module = module; this.code = code; this.args = args; this.defaultMessage = defaultMessage; } public BaseException(String module, String code, Object[] args) { this(module, code, args, null); } public BaseException(String module, String defaultMessage) { this(module, null, null, defaultMessage); } public BaseException(String code, Object[] args) { this(null, code, args, null); } public BaseException(String defaultMessage) { this(null, null, null, defaultMessage); } public String getModule() { return module; } public String getCode() { return code; } public Object[] getArgs() { return args; } public String getDefaultMessage() { return defaultMessage; } } <-------------------------------Gorgeous split line---------------------> /** * File upload error exception class * * @author */ public class InvalidExtensionException extends FileUploadException { private static final long serialVersionUID = 1L; private String[] allowedExtension; private String extension; private String filename; public InvalidExtensionException(String[] allowedExtension, String extension, String filename) { super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]"); this.allowedExtension = allowedExtension; this.extension = extension; this.filename = filename; } public String[] getAllowedExtension() { return allowedExtension; } public String getExtension() { return extension; } public String getFilename() { return filename; } public static class InvalidImageExtensionException extends InvalidExtensionException { private static final long serialVersionUID = 1L; public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) { super(allowedExtension, extension, filename); } } public static class InvalidFlashExtensionException extends InvalidExtensionException { private static final long serialVersionUID = 1L; public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) { super(allowedExtension, extension, filename); } } public static class InvalidMediaExtensionException extends InvalidExtensionException { private static final long serialVersionUID = 1L; public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) { super(allowedExtension, extension, filename); } } public static class InvalidVideoExtensionException extends InvalidExtensionException { private static final long serialVersionUID = 1L; public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) { super(allowedExtension, extension, filename); } } }
Switch storage mode
At present, minio storage is used by default. You can specify the file interface to be used through the annotation @ Primary
@Primary @Service public class LocalSysFileServiceImpl implements ISysFileService { ..... }
Local file store: localsysfileserviceimpl java
Minio file store: miniosysfileserviceimpl java
MinIO storage
Download method
Windows platform installation package download
Can from https://min.io/download#/windows Download Minio Exe executable file.
After Windows Downloads, create a new directory to store minio files, such as D: \ miniodata. Run minio directly under cmd exe server D:\minioData.
After successful startup, as shown in the following figure, the last red word prompts to modify access Key and Secret Key
If you feel that the official website is slow to download, you can use the online disk address I share: https://pan.baidu.com/s/1E9J52g6uW_VFWY34fHL6zA Extraction code: vneh
Open the console
minio provides a visual management and control platform. After installation, enter it in the browser( http://localhost:9000/ (opens new window)) can be accessed. The default user name and password are minioadmin
How to use
Minio configuration
minio: url: http://127.0.0.1:9000 # account number accessKey: minioadmin # password secretKey: minioadmin # MinIO bucket name bucketName: ruoyi
Create bucket
Select the + sign in the background management interface to create your Create Bucket, which can be understood as a folder for storing pictures. After the bucket is created successfully, you can upload pictures.
minio
Upload pictures
In the background management interface, select the + sign to upload your Upload file and upload your own picture. You can see the picture on the right side of the file list.
minio
Access policy
If * ReadOnly is set, all users can access through the file path, and the private bucket does not need to set the access policy.
Start the application and open it in the browser( http://127.0.0.1:9000/zenhanxin/e9f2a1a42fe591016b05f6a6a5c3c2d.png )You can access the picture.
If the code is missing, please contact me in time
QQ: 1354031513