欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JAVA如何判斷上傳文件后綴名是否符合規(guī)范MultipartFile

 更新時(shí)間:2023年11月29日 10:30:57   作者:coder阿龍  
這篇文章主要介紹了JAVA判斷上傳文件后綴名是否符合規(guī)范MultipartFile,文中通過實(shí)例代碼介紹了java實(shí)現(xiàn)對(duì)上傳文件做安全性檢查,需要的朋友可以參考下

JAVA判斷上傳文件后綴名是否符合規(guī)范MultipartFile

這里就只做了圖片判斷,其他判斷均一樣的邏輯

文件后綴名枚舉

    //文件類型
    public static String IMG_TYPE_PNG = "PNG";
    public static String IMG_TYPE_JPG = "JPG";
    public static String IMG_TYPE_JPEG = "JPEG";
    public static String IMG_TYPE_DMG = "BMP";
    public static String IMG_TYPE_GIF = "GIF";
    public static String IMG_TYPE_SVG = "SVG";

controller

 @PostMapping("/uploadFlatMap")
    public Result<String> uploadFlatMap(
          @RequestPart(value = "file",required = true) MultipartFile file){
        if(StringUtils.isEmpty(file.getName())){
            return sendFailedMsg(EnumUtil.BUS_ENUM.FILE_NOTFONUD_ERROR.KEY,file.getOriginalFilename());
        }
        log.info("正在做上傳操作,上傳文件為:{}",file.getOriginalFilename());
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if(!(Consts.IMG_TYPE_DMG.equals(suffix.toUpperCase()) ||
                Consts.IMG_TYPE_GIF.equals(suffix.toUpperCase()) ||
                Consts.IMG_TYPE_JPEG.equals(suffix.toUpperCase()) ||
                Consts.IMG_TYPE_JPG.equals(suffix.toUpperCase()) ||
                Consts.IMG_TYPE_PNG.equals(suffix.toUpperCase()) ||
                Consts.IMG_TYPE_SVG.equals(suffix.toUpperCase()))){
            return sendFailedMsg(EnumUtil.BUS_ENUM.FILE_TYPE_ERROR.KEY,file.getOriginalFilename());
        }

java實(shí)現(xiàn)對(duì)上傳文件做安全性檢查

對(duì)外接口支持文件上傳功能時(shí),為避免有人惡意上傳有毒或者篡改程序的腳本,需要對(duì)上傳的文件添加安全性校驗(yàn)。

1.文件后綴校驗(yàn)

文件首先校驗(yàn)直觀文件上傳格式,校驗(yàn)文件后綴是否符合業(yè)務(wù)要求。以MultipartFile類為例

        String fileName = file.getOriginalFilename();
        if (Strings.isEmpty(fileName)) {
            throw new RuntimeException("文件名未找到");
        }
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        if (!Objects.equal(suffix, "xls") && !Objects.equal(suffix, "xlsx")) {
            throw new RuntimeException("文件類型不正確,需要為xls或者xlsx");
        }

2.校驗(yàn)文件頭

由于文件后綴可能涉及到篡改的情況出現(xiàn),因此需要校驗(yàn)文件的魔數(shù),也就是文件頭。無論這個(gè)文件是否修改文件后綴,這個(gè)文件的文件頭是不會(huì)改變的。下面是常用的文件頭格式:

1.使用枚舉類去校驗(yàn)

JPEG (jpg),文件頭:FFD8FFE1
PNG (png),文件頭:89504E47
GIF (gif),文件頭:47494638
TIFF (tif),文件頭:49492A00
Windows Bitmap (bmp),文件頭:424D
CAD (dwg),文件頭:41433130
Adobe Photoshop (psd),文件頭:38425053
Rich Text Format (rtf),文件頭:7B5C727466
XML (xml),文件頭:3C3F786D6C
HTML (html),文件頭:68746D6C3E
Email [thorough only] (eml),文件頭:44656C69766572792D646174653A
Outlook Express (dbx),文件頭:CFAD12FEC5FD746F
Outlook (pst),文件頭:2142444E
MS Word/Excel (xls.or.doc),文件頭:D0CF11E0
MS Access (mdb),文件頭:5374616E64617264204A
WordPerfect (wpd),文件頭:FF575043
Postscript (eps.or.ps),文件頭:252150532D41646F6265
Adobe Acrobat (pdf),文件頭:255044462D312E
Quicken (qdf),文件頭:AC9EBD8F
Windows Password (pwl),文件頭:E3828596
ZIP Archive (zip),文件頭:504B0304
RAR Archive (rar),文件頭:52617221
Wave (wav),文件頭:57415645
AVI (avi),文件頭:41564920
Real Audio (ram),文件頭:2E7261FD
Real Media (rm),文件頭:2E524D46
MPEG (mpg),文件頭:000001BA
MPEG (mpg),文件頭:000001B3
Quicktime (mov),文件頭:6D6F6F76
Windows Media (asf),文件頭:3026B2758E66CF11
MIDI (mid),文件頭:4D546864

使用上面的文件頭去校驗(yàn)的代碼示例(這段代碼參考:Java 實(shí)戰(zhàn)系列·Magic 魔數(shù)獲取文件類型):

1.魔數(shù)枚舉類
public enum FileType {
    /**
     * JPEG
     */
    JPEG("JPEG", "FFD8FF"),
    /**
     * PNG
     */
    PNG("PNG", "89504E47"),
    /**
     * GIF
     */
    GIF("GIF", "47494638"),
    /**
     * TIFF
     */
    TIFF("TIFF", "49492A00"),
    /**
     * Windows bitmap
     */
    BMP("BMP", "424D"),
    /**
     * CAD
     */
    DWG("DWG", "41433130"),
    /**
     * Adobe photoshop
     */
    PSD("PSD", "38425053"),
    /**
     * Rich Text Format
     */
    RTF("RTF", "7B5C727466"),
    /**
     * XML
     */
    XML("XML", "3C3F786D6C"),
    /**
     * HTML
     */
    HTML("HTML", "68746D6C3E"),
    /**
     * Outlook Express
     */
    DBX("DBX", "CFAD12FEC5FD746F "),
    /**
     * Outlook
     */
    PST("PST", "2142444E"),
    /**
     * doc;xls;dot;ppt;xla;ppa;pps;pot;msi;sdw;db
     */
    OLE2("OLE2", "0xD0CF11E0A1B11AE1"),
    /**
     * Microsoft Word/Excel
     */
    XLS_DOC("XLS_DOC", "D0CF11E0"),
    /**
     * Microsoft Access
     */
    MDB("MDB", "5374616E64617264204A"),
    /**
     * Word Perfect
     */
    WPB("WPB", "FF575043"),
    /**
     * Postscript
     */
    EPS_PS("EPS_PS", "252150532D41646F6265"),
    /**
     * Adobe Acrobat
     */
    PDF("PDF", "255044462D312E"),
    /**
     * Windows Password
     */
    PWL("PWL", "E3828596"),
    /**
     * ZIP Archive
     */
    ZIP("ZIP", "504B0304"),
    /**
     * ARAR Archive
     */
    RAR("RAR", "52617221"),
    /**
     * WAVE
     */
    WAV("WAV", "57415645"),
    /**
     * AVI
     */
    AVI("AVI", "41564920"),
    /**
     * Real Audio
     */
    RAM("RAM", "2E7261FD"),
    /**
     * Real Media
     */
    RM("RM", "2E524D46"),
    /**
     * Quicktime
     */
    MOV("MOV", "6D6F6F76"),
    /**
     * Windows Media
     */
    ASF("ASF", "3026B2758E66CF11"),
    /**
     * MIDI
     */
    MID("MID", "4D546864");
    private String key;
    private String value;
    FileType(String key, String value) {
        this.key = key;
        this.value = value;
    }
    public String getValue() {
        return value;
    }
    public String getKey() {
        return key;
    }
}
2.獲取文件頭,并校驗(yàn)是否為Excel
public class FileUtil {
    /**
     * 獲取文件投
     *
     * @param filePath 文件路徑
     * @return 16 進(jìn)制的文件投信息
     *
     * @throws IOException
     */
    private static String getFileHeader(String filePath) throws IOException {
        byte[] b = new byte[28];
        InputStream inputStream = new FileInputStream(filePath);
        inputStream.read(b, 0, 28);
        inputStream.close();
        return bytes2hex(b);
    }
    /**
     * 將字節(jié)數(shù)組轉(zhuǎn)換成16進(jìn)制字符串
     */
    private static String bytes2hex(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
    /**
     * 校驗(yàn)是否為excel
     *
     * @param filePath 文件路徑
     * @return 文件類型
     *
     * @throws IOException
     */
    public static boolean checkIsExcel(String filePath) throws IOException {
        String fileHead = getFileHeader(filePath);
        if (null == fileHead || fileHead.length() == 0) {
            return false;
        }
        //校驗(yàn)是否為xls或者xlsx文件
        if (Objects.equal(fileHead, FileType.OLE2.getValue()) || Objects.equal(fileHead, FileType.XLS_DOC.getValue())) {
            return true;
        }
        return false;
    }
}

除了用上面的魔數(shù)頭去校驗(yàn),也可以用poi提供的枚舉類FileMagic工具類去校驗(yàn):

2.FileMagic校驗(yàn)文件頭

FileMagic魔數(shù)值解釋:

    OLE2(-2226271756974174256L),   //xls
    OOXML(new int[]{80, 75, 3, 4}), //xlsx, OOXML全稱是Office Open XML,OOXML是由微軟公司為Office 2007產(chǎn)品開發(fā)的技術(shù)規(guī)范,現(xiàn)已成為國際文檔格式標(biāo)準(zhǔn),兼容前國際標(biāo)準(zhǔn)ODF(Open Document Format)和中國文檔標(biāo)準(zhǔn)UOF(Unified Office document Format)。
    XML(new int[]{60, 63, 120, 109, 108}),  //xml
    BIFF2(new int[]{9, 0, 4, 0, 0, 0, 63, 0}), //Excel 2 現(xiàn)在office已經(jīng)不支持
    BIFF3(new int[]{9, 2, 6, 0, 0, 0, 63, 0}),//Excel 3現(xiàn)在office已經(jīng)不支持
    BIFF4(new byte[][]{{9, 4, 6, 0, 0, 0, 63, 0}, {9, 4, 6, 0, 0, 0, 0, 1}}),//Excel 4 現(xiàn)在office已經(jīng)不支持
    MSWRITE(new byte[][]{{49, -66, 0, 0}, {50, -66, 0, 0}}),  //微軟原來的寫入流,這個(gè)不清楚是否還能使用。
    RTF(new String[]{"{\\rtf"}),  //rtf
    PDF(new String[]{"%PDF"}), //pdf
    HTML(new String[]{"<!DOCTYP", "<html", "\n\r<html", "\r\n<html", "\r<html", "\n<html", "<HTML", "\r\n<HTML", "\n\r<HTML", "\r<HTML", "\n<HTML"}),  //HTML
    WORD2(new int[]{219, 165, 45, 0}),//word
    JPEG(new byte[][]{{-1, -40, -1, -37}, {-1, -40, -1, -32, 63, 63, 74, 70, 73, 70, 0, 1}, {-1, -40, -1, -18}, {-1, -40, -1, -31, 63, 63, 69, 120, 105, 102, 0, 0}}),//圖片驗(yàn)證,jpeg格式
    GIF(new String[]{"GIF87a", "GIF89a"}),//圖片驗(yàn)證,gif格式
    PNG(new int[]{137, 80, 78, 71, 13, 10, 26, 10}),//圖片驗(yàn)證,png格式
    TIFF(new String[]{"II*\u0000", "MM\u0000*"}),//圖片驗(yàn)證,tiff格式
    WMF(new int[]{215, 205, 198, 154}),//圖片驗(yàn)證,wmf格式
    EMF(new int[]{1, 0, 0, 0, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 32, 69, 77, 70}),//圖片驗(yàn)證,emf格式
    BMP(new int[]{66, 77}),//圖片驗(yàn)證,nmp格式
    UNKNOWN(new byte[][]{new byte[0]});//未知魔數(shù)

使用魔數(shù)校驗(yàn)Excel文件代碼:

 private static boolean checkIsExcel(InputStream inputStream) throws IOException {
 	//獲取文件流的文件頭
     FileMagic fileMagic = FileMagic.valueOf(inputStream);
     //判斷Excel文件頭是否符合xls或者xlsx
     if (Objects.equal(fileMagic, FileMagic.OLE2) || Objects.equal(fileMagic, FileMagic.OOXML)) {
         return true;
     }
     return false;
 }

3.校驗(yàn)文件大小

為了避免上傳過大文件,影響服務(wù)器性能以及帶寬。需要對(duì)文件大小進(jìn)行校驗(yàn),具體文件大小控制以業(yè)務(wù)為主。

4.示例

以校驗(yàn)Excel文件為例:

 /**
     * 校驗(yàn)文件
     *
     * @param file 文件
     * @param fileMaxSize  文件大小限制
     */
    public static void checkExcel(MultipartFile file, Double fileMaxSize) {
        // 文件類型判斷 - 校驗(yàn)文件后綴
        String fileName = file.getOriginalFilename();
        if (Strings.isEmpty(fileName)) {
            throw new RuntimeException("文件名未找到");
        }
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        if (!Objects.equal(suffix, "xls") && !Objects.equal(suffix, "xlsx")) {
            throw new RuntimeException("文件類型不正確,需要為xls或者xlsx");
        }
        // 文件類型判斷 - 校驗(yàn)文件頭內(nèi)容
        try (InputStream inputStream = file.getInputStream()) {
            // 獲取到上傳文件的文件頭信息
            boolean isExcel = checkIsExcel(inputStream);
            if (!isExcel) {
                throw new RuntimeException("文件類型不正確,原文件類型需要為xls");
            }
        } catch (IOException e) {
            log.error("Get file input stream failed.", e);
            throw new RuntimeException("文件上傳失敗");
        }
        // 文件大小校驗(yàn) - 單位:MB
        long fileBytes = file.getSize();
        double fileSize = (double) fileBytes / 1048576;
        if (fileSize <= 0) {
            throw new RuntimeException("文件內(nèi)容為空");
        }
        if (fileSize > fileMaxSize) {
            throw new RuntimeException("文件上傳內(nèi)容大小超出限制");
        }
    }
    /**
     * 校驗(yàn)文件頭
     *
     * @param inputStream
     * @return
     *
     * @throws IOException
     */
    private static boolean checkIsExcel(InputStream inputStream) throws IOException {
        FileMagic fileMagic = FileMagic.valueOf(inputStream);
        if (Objects.equal(fileMagic, FileMagic.OLE2) || Objects.equal(fileMagic, FileMagic.OOXML)) {
            return true;
        }
        return false;
    }

到此這篇關(guān)于JAVA判斷上傳文件后綴名是否符合規(guī)范MultipartFile的文章就介紹到這了,更多相關(guān)java上傳文件后綴名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java JDK動(dòng)態(tài)代理實(shí)現(xiàn)原理實(shí)例解析

    Java JDK動(dòng)態(tài)代理實(shí)現(xiàn)原理實(shí)例解析

    這篇文章主要介紹了Java JDK動(dòng)態(tài)代理實(shí)現(xiàn)原理實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 關(guān)于Java Spring三級(jí)緩存和循環(huán)依賴的深入理解

    關(guān)于Java Spring三級(jí)緩存和循環(huán)依賴的深入理解

    對(duì)于循環(huán)依賴,我相信讀者無論只是聽過也好,還是有過了解也好,至少都有所接觸。但是我發(fā)現(xiàn)目前許多博客對(duì)于循環(huán)依賴的講解并不清楚,都提到了Spring的循環(huán)依賴解決方案是三級(jí)緩存,但是三級(jí)緩存每一級(jí)的作用是什么,很多博客都沒有提到,本篇文章帶你深入了解
    2021-09-09
  • Java按照添加順序的集合幾種方法詳解

    Java按照添加順序的集合幾種方法詳解

    這篇文章主要介紹了Java按照添加順序的集合幾種方法的相關(guān)資料,文中介紹了Java中五種常用的數(shù)據(jù)結(jié)構(gòu)(ArrayList、LinkedList、LinkedHashSet、LinkedHashMap、Stream)及其特點(diǎn),適合不同的應(yīng)用場景,需要的朋友可以參考下
    2024-12-12
  • Spring中的@Aspect注解使用詳解

    Spring中的@Aspect注解使用詳解

    這篇文章主要介紹了Spring中的@Aspect注解使用詳解,利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率,需要的朋友可以參考下
    2024-01-01
  • springboot如何重定向外部網(wǎng)頁

    springboot如何重定向外部網(wǎng)頁

    這篇文章主要介紹了springboot如何重定向外部網(wǎng)頁,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 使用Java實(shí)現(xiàn)Excel轉(zhuǎn)PDF的示例詳解

    使用Java實(shí)現(xiàn)Excel轉(zhuǎn)PDF的示例詳解

    在實(shí)際的開發(fā)過程中,我們常常會(huì)遇到需要將 Excel 文件轉(zhuǎn)換為 PDF 文件的需求,本文為大家介紹一種Java中的常見實(shí)現(xiàn)方式,需要的可以參考一下
    2025-02-02
  • 關(guān)于Java反射機(jī)制 你需要知道的事情

    關(guān)于Java反射機(jī)制 你需要知道的事情

    這篇文章主要介紹了Java反射機(jī)制的相關(guān)內(nèi)容,涉及了class類的動(dòng)態(tài)加載,獲取成員變量、構(gòu)造函數(shù)信息等信息,需要的朋友可以參考下。
    2017-09-09
  • 帶你入門Java的泛型

    帶你入門Java的泛型

    這篇文章主要給大家介紹了關(guān)于Java中泛型使用的簡單方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • Eureka源碼核心類預(yù)備知識(shí)

    Eureka源碼核心類預(yù)備知識(shí)

    這篇文章主要為大家介紹了Eureka源碼核心類預(yù)備知識(shí)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • JavaCV 圖像邊緣檢測之Canny 算法詳解

    JavaCV 圖像邊緣檢測之Canny 算法詳解

    在圖像處理中,邊緣檢測是基礎(chǔ)且關(guān)鍵的一環(huán),其中Canny邊緣檢測算法以其高精度和可靠性著稱,本文詳細(xì)介紹了使用JavaCV庫實(shí)現(xiàn)Canny算法的原理和步驟,結(jié)合代碼示例和案例分析,展示了Canny算法在Java環(huán)境下的實(shí)現(xiàn)過程和邊緣檢測效果
    2024-11-11

最新評(píng)論