上传文件类型验证

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface PermitFileCategory {

    /**
     * 允许的文件类别
     * @return
     */
    FileCategoryEnum[] value();


}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface PermitFileType {

    /**
     * 允许的文件类别
     * @return
     */
    FileTypeEnum[] value();


}

public enum FileCategoryEnum {

    PICS("图片", FileTypeUtils.PICS),
    DOCS("文档", FileTypeUtils.DOCS),
    VIDEOS("视频", FileTypeUtils.VIDEOS),
    TORRENT("种子", FileTypeUtils.TORRENT),
    AUDIOS("音乐", FileTypeUtils.AUDIOS),
    OTHERS("其他", FileTypeUtils.OTHERS),
    ;

    private String desc;
    private FileTypeEnum[] fileTypeEnums;

    FileCategoryEnum(String desc, FileTypeEnum[] fileTypeEnums) {
        this.desc = desc;
        this.fileTypeEnums = fileTypeEnums;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public FileTypeEnum[] getFileTypeEnums() {
        return fileTypeEnums;
    }

    public void setFileTypeEnums(FileTypeEnum[] fileTypeEnums) {
        this.fileTypeEnums = fileTypeEnums;
    }
}
public enum FileTypeEnum {

    /**
     * JEPG.
     */
    JPEG("FFD8FF", ".jpeg"),

    /**
     * PNG.
     */
    PNG("89504E47", ".png"),

    /**
     * GIF.
     */
    GIF("47494638", ".gif"),

    /**
     * TIFF.
     */
    TIFF("49492A00", ".tif"),

    /**
     * Windows Bitmap.
     */
    BMP("424D", ".bmp"),

    /**
     * CAD.
     */
    DWG("41433130", ".dwg"),

    /**
     * Adobe Photoshop.
     */
    PSD("38425053", ".psd"),

    /**
     * Rich Text Format.
     */
    RTF("7B5C727466", ".rtf"),

    /**
     * XML.
     */
    XML("3C3F786D6C", ".xml"),

    /**
     * HTML.
     */
    HTML("68746D6C3E", ".html"),
    /**
     * CSS.
     */
    CSS("48544D4C207B0D0A0942", ".css"),
    /**
     * JS.
     */
    JS("696B2E71623D696B2E71", ".js"),
    /**
     * Email [thorough only].
     */
    EML("44656C69766572792D646174653A", ".eml"),

    /**
     * Outlook Express.
     */
    DBX("CFAD12FEC5FD746F", ".dbx"),

    /**
     * Outlook (pst).
     */
    PST("2142444E", ".pst"),

    /**
     * MS Word/Excel.
     */
    XLS("D0CF11E0", ".xls"),

    DOC("D0CF11E0", ".doc"),

    PPT("D0CF11E0", ".ppt"),

    XLSX("504B0304", ".xlsx"),

    DOCX("504B0304", ".docx"),

    PPTX("504B0304", ".pptx"),

    /**
     * Visio
     */
    VSD("d0cf11e0a1b11ae10000", ".vsd"),
    /**
     * MS Access.
     */
    MDB("5374616E64617264204A", ".mdb"),
    /**
     * WPS文字wps、表格et、演示dps都是一样的
     */
    WPS("d0cf11e0a1b11ae10000", ".wps"),
    /**
     * torrent
     */
    TORRENT("6431303A637265617465", ".torrent"),
    /**
     * WordPerfect.
     */
    WPD("FF575043", ".wpd"),

    /**
     * Postscript.
     */
    EPS("252150532D41646F6265", ".eps"),

    /**
     * Adobe Acrobat.
     */
    PDF("255044462D312E", ".pdf"),

    /**
     * Quicken.
     */
    QDF("AC9EBD8F", ".qdf"),

    /**
     * Windows Password.
     */
    PWL("E3828596", ".pwl"),

    /**
     * ZIP Archive.
     */
    ZIP("504B0304", ".zip"),

    /**
     * RAR Archive.
     */
    RAR("52617221", ".rar"),
    /**
     * JSP Archive.
     */
    JSP("3C2540207061676520", ".jsp"),
    /**
     * JAVA Archive.
     */
    JAVA("7061636B61676520", ".java"),
    /**
     * CLASS Archive.
     */
    CLASS("CAFEBABE0000002E00", ".class"),
    /**
     * JAR Archive.
     */
    JAR("504B03040A000000", ".jar"),
    /**
     * MF Archive.
     */
    MF("4D616E69666573742D56", ".mf"),
    /**
     *EXE Archive.
     */
    EXE("4D5A9000030000000400", ".exe"),
    /**
     *CHM Archive.
     */
    CHM("49545346030000006000", ".chm"),
    /*
     * INI("235468697320636F6E66"), SQL("494E5345525420494E54"), BAT(
     * "406563686F206f66660D"), GZ("1F8B0800000000000000"), PROPERTIES(
     * "6C6F67346A2E726F6F74"), MXP(
     * "04000000010000001300"),
     */
    /**
     * Wave.
     */
    WAV("57415645", ".wav"),

    /**
     * AVI.
     */
    AVI("41564920", ".avi"),

    /**
     * Real Audio.
     */
    RAM("2E7261FD", ".ram"),

    /**
     * Real Media.
     */
    RM("2E524D46", ".rm"),

    /** Real Media (rm) rmvb/rm相同  */
    RMVB("2E524D46000000120001", ".rmvb"),

    /**
     * MPEG (mpg).
     */
    MPG("000001BA", ".mpg"),

    /**
     * Quicktime.
     */
    MOV("6D6F6F76", ".mov"),

    /**
     * Windows Media.
     */
    ASF("3026B2758E66CF11", ".asf"),

    /**
     * MIDI.
     */
    MID("4D546864", ".mid"),
    /**
     * MP4.
     */
    MP4("00000020667479706973", ".mp4"),
    /**
     * MP3.
     */
    MP3("49443303000000002176", ".mp3"),

    TXT("TXT----TXT", ".txt"),

    /**
     * FLV.
     */
    FLV("464C5601050000000900", ".flv");

    private String value;
    private String fileNameSuffix;

    FileTypeEnum(String value, String fileNameSuffix) {
        this.value = value;
        this.fileNameSuffix = fileNameSuffix;
    }

    public static FileTypeEnum getFileTypeEnum(String value) {
        if (StringUtils.isEmpty(value)) {
            return null;
        }

        for (FileTypeEnum fileTypeEnum : FileTypeEnum.values()) {
            if (fileTypeEnum.getValue().equalsIgnoreCase(value)) {
                return fileTypeEnum;
            }
        }

        return null;
    }


    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getFileNameSuffix() {
        return fileNameSuffix;
    }

    public void setFileNameSuffix(String fileNameSuffix) {
        this.fileNameSuffix = fileNameSuffix;
    }
}
public class FileTypeUtils {

    private static final Logger logger = LoggerFactory.getLogger(FileTypeUtils.class);

    public static final FileTypeEnum[] PICS = {FileTypeEnum.JPEG, FileTypeEnum.PNG, FileTypeEnum.GIF, FileTypeEnum.TIFF, FileTypeEnum.BMP, FileTypeEnum.DWG, FileTypeEnum.PSD};

    public static final FileTypeEnum[] DOCS = {FileTypeEnum.RTF, FileTypeEnum.XML, FileTypeEnum.HTML, FileTypeEnum.CSS, FileTypeEnum.JS, FileTypeEnum.EML, FileTypeEnum.DBX, FileTypeEnum.PST, FileTypeEnum.XLS, FileTypeEnum.DOC, FileTypeEnum.XLSX, FileTypeEnum.DOCX, FileTypeEnum.VSD,
            FileTypeEnum.MDB, FileTypeEnum.WPS, FileTypeEnum.WPD, FileTypeEnum.EPS, FileTypeEnum.PDF, FileTypeEnum.QDF, FileTypeEnum.PWL, FileTypeEnum.ZIP, FileTypeEnum.RAR, FileTypeEnum.JSP, FileTypeEnum.JAVA, FileTypeEnum.CLASS,
            FileTypeEnum.JAR, FileTypeEnum.MF, FileTypeEnum.EXE, FileTypeEnum.CHM, FileTypeEnum.PPTX, FileTypeEnum.PPT, FileTypeEnum.TXT};

    public static final FileTypeEnum[] VIDEOS = {FileTypeEnum.AVI, FileTypeEnum.RAM, FileTypeEnum.RM, FileTypeEnum.RMVB, FileTypeEnum.MPG, FileTypeEnum.MOV, FileTypeEnum.ASF, FileTypeEnum.MP4, FileTypeEnum.FLV, FileTypeEnum.MID};

    public static final FileTypeEnum[] TORRENT = {FileTypeEnum.TORRENT};

    public static final FileTypeEnum[] AUDIOS = {FileTypeEnum.WAV, FileTypeEnum.MP3};

    public static final FileTypeEnum[] OTHERS = {};

    /**
     * 将文件头转换成16进制字符串
     *
     * @param src 原生byte
     * @return 16进制字符串
     */
    private static String bytesToHexString(byte[] src) {

        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 获取文件头
     *
     * @param is
     * @return
     */
    private static String getFileHead(InputStream is) {

        byte[] b = new byte[28];
        try {
            is.read(b, 0, 28);
        } catch (IOException e) {
            logger.error("读取文件头失败", e);
            return null;
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    logger.error("关闭文件流失败", e);
                    return null;
                }
            }
        }
        return bytesToHexString(b);
    }

    /**
     * 获取文件类型(返回一个)
     *
     * @param is
     * @return
     */
    public static @Nullable FileTypeEnum getFileType(InputStream is) {

        List<FileTypeEnum> fileTypeEnumList = getFileTypes(is);
        if (!CollectionUtils.isEmpty(fileTypeEnumList)) {
            return fileTypeEnumList.get(0);
        }

        return null;
    }

    /**
     * 获取文件类型(返回多个)
     *
     * @param is
     * @return
     */
    public static @Nullable List<FileTypeEnum> getFileTypes(InputStream is) {

        String fileHead = getFileHead(is);
        if (StringUtils.isEmpty(fileHead)) {
            return null;
        }

        fileHead = fileHead.toUpperCase();

        List<FileTypeEnum> fileTypeEnumList = new ArrayList<>();

        for (FileTypeEnum fileTypeEnum : FileTypeEnum.values()) {
            if (fileHead.startsWith(fileTypeEnum.getValue())) {
                fileTypeEnumList.add(fileTypeEnum);
            }
        }

        return fileTypeEnumList;
    }

    /**
     * 获取文件名后缀,获取不到时返回空(null) 例如: .png
     * @param is 文件流 注意传进来的文件流会被关闭
     * @return
     */
    @Deprecated
    public static @Nullable String obtainFileNameSuffix(InputStream is) {

        if (is != null) {
            FileTypeEnum fileTypeEnum = getFileType(is);
            if (fileTypeEnum != null) {
                return fileTypeEnum.getFileNameSuffix();
            }
        }
        return null;
    }

    /**
     * 获取文件名后缀,获取不到时返回空(null), 获取到多个时返回 defaultFileNameSuffix, 次方法用于魔数相同文件类型判断
     * 例如: xls, doc的魔数相同,defaultFileNameSuffix为 .xls, 则返回 .xls
     * @param is 文件流 注意传进来的文件流会被关闭
     * @param defaultFileNameSuffix 默认文件后缀名 例如 .xls
     * @return
     */
    public static @Nullable String obtainFileNameSuffix(InputStream is, String defaultFileNameSuffix) {

        if (is != null) {
            List<FileTypeEnum> fileTypeEnumList = getFileTypes(is);
            if (!CollectionUtils.isEmpty(fileTypeEnumList)) {
                for (FileTypeEnum fileTypeEnum : fileTypeEnumList) {
                    if (StringUtils.isNotEmpty(defaultFileNameSuffix) && fileTypeEnum.getFileNameSuffix().equalsIgnoreCase(defaultFileNameSuffix)) {
                        return fileTypeEnum.getFileNameSuffix();
                    }
                }
                return fileTypeEnumList.get(0).getFileNameSuffix();
            }
        }
        return null;
    }

    /**
     * 获取文件名类型,获取不到时返回空(null), 获取到多个时返回 defaultFileNameSuffix, 次方法用于魔数相同文件类型判断
     * 例如: xls, doc的魔数相同,defaultFileNameSuffix为 .xls, 则返回 XLS
     * @param is 文件流 注意传进来的文件流会被关闭
     * @param defaultFileNameSuffix 默认文件后缀名 例如 .xls
     * @return
     */
    public static @Nullable FileTypeEnum obtainFileTypeEnum(InputStream is, String defaultFileNameSuffix) {

        if (is != null) {
            List<FileTypeEnum> fileTypeEnumList = getFileTypes(is);
            if (!CollectionUtils.isEmpty(fileTypeEnumList)) {
                for (FileTypeEnum fileTypeEnum : fileTypeEnumList) {
                    if (StringUtils.isNotEmpty(defaultFileNameSuffix) && fileTypeEnum.getFileNameSuffix().equalsIgnoreCase(defaultFileNameSuffix)) {
                        return fileTypeEnum;
                    }
                }
                return fileTypeEnumList.get(0);
            }
        }
        return null;
    }


    public static Boolean isPic(FileTypeEnum fileTypeEnum) {

        if (fileTypeEnum == null) {
            return false;
        }

        for (FileTypeEnum picEnum : PICS) {
            if (picEnum.equals(fileTypeEnum)) {
                return true;
            }
        }

        return false;
    }

    public static Boolean isFileTypeEnum(FileTypeEnum[] fileTypeEnums, FileTypeEnum fileTypeEnum) {

        if (fileTypeEnum == null || fileTypeEnums == null) {
            return false;
        }

        for (FileTypeEnum picEnum : fileTypeEnums) {
            if (picEnum.equals(fileTypeEnum)) {
                return true;
            }
        }

        return false;
    }

    public static Boolean isFileCategoryEnum(FileCategoryEnum oriFileCategoryEnum, FileTypeEnum fileTypeEnum) {

        if (fileTypeEnum == null || oriFileCategoryEnum == null) {
            return false;
        }

        FileCategoryEnum fileCategoryEnum = getFileCategoryEnum(fileTypeEnum);
        if (fileCategoryEnum != null && fileCategoryEnum.equals(oriFileCategoryEnum)) {
            return true;
        }

        return false;
    }

    public static FileCategoryEnum getFileCategoryEnum(FileTypeEnum fileTypeEnum) {

        if (fileTypeEnum == null) {
            return null;
        }

        if (isFileTypeEnum(FileCategoryEnum.PICS.getFileTypeEnums(), fileTypeEnum)) {
            return FileCategoryEnum.PICS;
        }

        if (isFileTypeEnum(FileCategoryEnum.DOCS.getFileTypeEnums(), fileTypeEnum)) {
            return FileCategoryEnum.DOCS;
        }

        if (isFileTypeEnum(FileCategoryEnum.VIDEOS.getFileTypeEnums(), fileTypeEnum)) {
            return FileCategoryEnum.VIDEOS;
        }

        if (isFileTypeEnum(FileCategoryEnum.TORRENT.getFileTypeEnums(), fileTypeEnum)) {
            return FileCategoryEnum.TORRENT;
        }

        if (isFileTypeEnum(FileCategoryEnum.AUDIOS.getFileTypeEnums(), fileTypeEnum)) {
            return FileCategoryEnum.AUDIOS;
        }

        return FileCategoryEnum.OTHERS;

    }


}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值