判断图片的像素, 视频的时长, 文件的类型, 文件的大小是否超过指定值

package com.topsports.decision.engine.common.core.util;

import com.topsports.decision.engine.common.core.exception.BizException;
import okhttp3.*;
import org.apache.tika.metadata.HttpHeaders;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaMetadataKeys;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.helpers.DefaultHandler;
import ws.schild.jave.MultimediaObject;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author yukun.yan
 * @description FileUploadUtils 目标文件根据自定义规则校验
 * @date 2023/5/17 14:48
 */
public class FileUploadUtils {

    private FileUploadUtils() {
        throw new UnsupportedOperationException();
    }

    /**
     * 初始化文件解析器
     */
    private static final AutoDetectParser parser = new AutoDetectParser();
    private static final ParseContext parseContext = new ParseContext();

    /**
     * 判断上传的图片文件像素是否超过指定值
     *
     * @param file      MultipartFile对象
     * @param maxPixels 最大像素值
     * @return true         表示图片像素没有超过指定值,false表示图片像素超过了指定值maxPixels
     */
    public static boolean isImagePixelExceeded(MultipartFile file, int maxPixels) {
        try (InputStream inputStream = file.getInputStream()) {
            BufferedImage image = ImageIO.read(inputStream);
            AssertUtils.notNull(image, BizException.biz("Invalid image file"));
            int width = image.getWidth();
            int height = image.getHeight();
            int pixels = width * height;
            return pixels < maxPixels;
        } catch (Exception e) {
            throw BizException.biz(e.getMessage());
        }
    }

    /**
     * 判断上传的视频文件时长是否超过指定值
     *
     * @param multipartFile     文件
     * @param maxDurationSecond 最大支持的视频时长(秒)
     * @return 不超过指定的秒数返回true
     */
    public static boolean isVideoDurationExceeded(MultipartFile multipartFile, int maxDurationSecond) {
        try {
            // 创建临时文件夹, 会自动删除
            File tempFile = File.createTempFile("temp", null);
            // 拷贝
            multipartFile.transferTo(tempFile);
            MultimediaObject multimediaObject = new MultimediaObject(tempFile);
            long durationMillisecond = multimediaObject.getInfo().getDuration();
            // 手动删除
            tempFile.delete();
            return durationMillisecond < maxDurationSecond * 1000L;
        } catch (Exception e) {
            throw BizException.biz(e.getMessage());
        }
    }

    /**
     * 判断上传的文件大小是否超过指定值
     *
     * @param file      文件
     * @param maxSizeMb 文件最大大小
     * @return 没有超过指定值maxSize, 返回true
     */
    public static boolean isSizeExceeded(MultipartFile file, long maxSizeMb) {
        if (!isFileExist(file)) {
            throw BizException.biz("File does not exist");
        }
        long size = file.getSize();
        // 没有超过指定值
        return size < (maxSizeMb * 1024 * 1024);
    }

    /**
     * 校验文件类型是不是我们预期的类型
     *
     * @param file              文件
     * @param expectedMimeTypes 预期的文件类型的Pattern, 可以自定义任意文件类型
     * @return 不匹配, 返回false
     */
    public static boolean isFileTypeMatch(MultipartFile file, List expectedMimeTypes) {
        // 获取文件类型
        String fileType = getFileRealType(file);
        for (Pattern expectedMimeType : expectedMimeTypes) {
            if (expectedMimeType.matcher(fileType).matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取文件类型, 根据文件后缀名判断无法准确判断类型
     *
     * @param file
     * @return
     */
    public static String getFileRealType(MultipartFile file) {
        Metadata metadata = new Metadata();
        metadata.add(TikaMetadataKeys.RESOURCE_NAME_KEY, file.getName());
        try (InputStream stream = file.getInputStream()) {
            parser.parse(stream, new DefaultHandler(), metadata, parseContext);
        } catch (Exception e) {
            throw BizException.biz(e.getMessage());
        }
        return metadata.get(HttpHeaders.CONTENT_TYPE);
    }

    /**
     * 根据使用HTTP/2获取网络资源
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static MultipartFile getMultipartFileByHttp2(String url) {
        OkHttpClient client = new OkHttpClient.Builder()
                .protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1))
                .build();
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response;
        try {
            response = client.newCall(request).execute();
        } catch (Exception e) {
            throw BizException.biz(e.getMessage());
        }
        AssertUtils.isTrue(response.isSuccessful(), BizException.biz("Unexpected response code:%s" + response.code()));
        ResponseBody body = response.body();
        AssertUtils.notNull(body, BizException.biz("response body is null"));

        try (InputStream inputStream = body.byteStream()) {
            String fileName = interceptFileNameByUrl(url);
            return new MockMultipartFile(fileName, fileName, MediaType.MULTIPART_FORM_DATA_VALUE, inputStream);
        } catch (Exception e) {
            throw BizException.biz(e.getMessage());
        }
    }

    /**
     * 根据url截取文件名
     *
     * @param url
     * @return
     */
    public static String interceptFileNameByUrl(String url) {
        if (StringUtils.isBlank(url)) {
            throw new IllegalArgumentException("url is null");
        }
        return url.substring(url.lastIndexOf("/") + 1);
    }

    /**
     * 指定文件是否存在
     *
     * @param file
     * @return
     */
    public static boolean isFileExist(MultipartFile file) {
        return file != null && !file.isEmpty();
    }

}

用到maven依赖


                commons-fileupload
                commons-fileupload
                1.4
                compile
            
            
                ws.schild
                jave-all-deps
                3.3.1
            
            
                org.apache.tika
                tika-core
                1.24.1
            

你可能感兴趣的:(java,spring,apache)