java file upload (local storage and Minio storage)

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

Keywords: Java

Added by xbuzzx on Tue, 01 Feb 2022 12:35:08 +0200