最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 校驗(yàn)用戶上傳的圖片文件(兩種方式)

 更新時(shí)間:2023年11月09日 12:02:13   作者:Doker 多克  
圖片上傳是現(xiàn)代應(yīng)用中非常常見的一種功能,也是風(fēng)險(xiǎn)比較高的一個(gè)地方,惡意用戶可能會(huì)上傳一些病毒、木馬,本文給大家介紹兩種對(duì)圖片文件進(jìn)行校驗(yàn)的方法,感興趣的朋友一起看看吧

圖片上傳是現(xiàn)代應(yīng)用中非常常見的一種功能,也是風(fēng)險(xiǎn)比較高的一個(gè)地方。惡意用戶可能會(huì)上傳一些病毒、木馬。這些東西不僅嚴(yán)重威脅服務(wù)器的安全還浪費(fèi)了帶寬,磁盤等資源。所以,在圖片上傳的接口中,一定要對(duì)用戶上傳的文件進(jìn)行嚴(yán)格的校驗(yàn)。

本文介紹了 2 種對(duì)圖片文件進(jìn)行驗(yàn)證的方法可供你參考。

一、文件后綴校驗(yàn)

通過文件后綴(也就是文件擴(kuò)展名,通常用于表示文件的類型),進(jìn)行文件類型校驗(yàn)這是最常見的做法。

圖片文件的后綴類型有很多,常見的只有:jpg、jpeggif、png、webp。我們可以在配置或者代碼中定義一個(gè)“允許上傳的圖片后綴”集合,用于校驗(yàn)用戶上傳的圖片文件。

package cn.springdoc.demo.web.controller;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/upload")
public class UploadController {
    // 允許上傳的圖片類型的后綴集合
    static final Set<String> imageSuffix = Set.of("jpg", "jpeg", "gif", "png", "webp");
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<String> upload (@RequestParam("file") MultipartFile file ) throws IllegalStateException, IOException{
        // 文件的原始名稱
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return ResponseEntity.badRequest().body("文件名稱不能為空");
        }
        // 解析出文件后綴
        int index = fileName.lastIndexOf(".");
        if (index == -1) {
            return ResponseEntity.badRequest().body("文件后綴不能為空");
        }
        String suffix = fileName.substring(index + 1);
        if (!imageSuffix.contains(suffix.trim().toLowerCase())) {
            return ResponseEntity.badRequest().body("非法的文件類型");
        }
        // IO 到程序運(yùn)行目錄下的 public 目錄,這是默認(rèn)的靜態(tài)資源目錄
        Path dir = Paths.get(System.getProperty("user.dir"), "public");
        if (!Files.isDirectory(dir)) {
            // 創(chuàng)建目錄
            Files.createDirectories(dir);
        }
        file.transferTo(dir.resolve(fileName));
        // 返回相對(duì)訪問路徑
        return ResponseEntity.ok("/" + fileName);
    }
}

如上,代碼很簡單。先是獲取客戶端文件的名稱,再從名稱獲取到文件的后綴。確定是合法文件后再 IO 到本地磁盤。

二、使用 ImageIO 校驗(yàn)

由于文件的后綴是可編輯的,惡意用戶可以把一個(gè) exe 文件的后綴改為 jpg 再上傳到服務(wù)器。于是這種情況下,上面的這種校驗(yàn)方式就會(huì)失效,惡意文件會(huì)被 IO 到磁盤。

在基于上面的方法進(jìn)行校驗(yàn)后,我們可以先把文件 IO 到臨時(shí)目錄,再使用 ImageIO 類去加載圖片文件,如果 Images 加載的文件不是圖片,則會(huì)返回 null。

package cn.springdoc.demo.web.controller;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/upload")
public class UploadController {
    // 允許上傳的圖片類型的后綴集合
    static final Set<String> imageSuffix = Set.of("jpg", "jpeg", "gif", "png", "webp");
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file)
            throws IllegalStateException, IOException {
        // 文件的原始名稱
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return ResponseEntity.badRequest().body("文件名稱不能為空");
        }
        // 解析出文件后綴
        int index = fileName.lastIndexOf(".");
        if (index == -1) {
            return ResponseEntity.badRequest().body("文件后綴不能為空");
        }
        String suffix = fileName.substring(index + 1);
        if (!imageSuffix.contains(suffix.trim().toLowerCase())) {
            return ResponseEntity.badRequest().body("非法的文件類型");
        }
        // 獲取系統(tǒng)中的臨時(shí)目錄
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        // 臨時(shí)文件使用 UUID 隨機(jī)命名
        Path tempFile = tempDir.resolve(Paths.get(UUID.randomUUID().toString()));
        // copy 到臨時(shí)文件
        file.transferTo(tempFile);
        try {
            // 使用 ImageIO 讀取文件
            if (ImageIO.read(tempFile.toFile()) == null) {
                return ResponseEntity.badRequest().body("非法的文件類型");
            }
            // 至此,這的確是一個(gè)圖片資源文件
            // IO 到運(yùn)行目錄下的 public 目錄
            Path dir = Paths.get(System.getProperty("user.dir"), "public");
            if (!Files.isDirectory(dir)) {
                // 創(chuàng)建目錄
                Files.createDirectories(dir);
            }
            Files.copy(tempFile, dir.resolve(fileName));
            // 返回相對(duì)訪問路徑
            return ResponseEntity.ok("/" + fileName);
        } finally {
            // 始終刪除臨時(shí)文件
            Files.delete(tempFile);
        }
    }
}

這種方式更為嚴(yán)格,不但要校驗(yàn)文件后綴還要校驗(yàn)文件內(nèi)容。弊端也顯而易見,會(huì)耗費(fèi)更多的資源!

1、ImageIO.read 方法

最后說一下 ImageIO.read 方法,它會(huì)從系統(tǒng)中已注冊(cè)的 ImageReader 中選擇一個(gè) Reader 對(duì)圖片進(jìn)行解碼,如果沒有 Reader 能夠解碼文件,則返回 null。也就是說,如果上傳的圖片類型,在系統(tǒng)中沒有對(duì)應(yīng)的 ImageReader 也會(huì)被當(dāng)做是“非法文件”。

例如:webp 類型的圖片文件,ImageIO.read 就讀取不了,因?yàn)?JDK 沒有預(yù)置讀取 webp 圖片的 ImageReader

要解決這個(gè)問題,可以添加一個(gè) webp-imageio 依賴。

<!-- https://mvnrepository.com/artifact/org.sejda.imageio/webp-imageio -->
<dependency>
    <groupId>org.sejda.imageio</groupId>
    <artifactId>webp-imageio</artifactId>
    <version>0.1.6</version>
</dependency>

webp-imageio 庫提供了 webp 圖片的 ImageReader 實(shí)現(xiàn),并以 SPI 的形式注冊(cè)到了系統(tǒng)中,不要寫其他任何代碼就可以成功讀取。

到此這篇關(guān)于Spring Boot 校驗(yàn)用戶上傳的圖片文件的文章就介紹到這了,更多相關(guān)Spring Boot 校驗(yàn)上傳圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java程序中foreach用法示例

    java程序中foreach用法示例

    這篇文章主要介紹了java程序中foreach用法示例,需要的朋友可以參考下
    2014-04-04
  • SpringCloud?Nacos服務(wù)分級(jí)存儲(chǔ)模型詳解

    SpringCloud?Nacos服務(wù)分級(jí)存儲(chǔ)模型詳解

    Nacos服務(wù)分級(jí)存儲(chǔ)模型是Nacos存儲(chǔ)服務(wù)注冊(cè)信息和配置信息的核心模型之一,本文將對(duì)?Nacos?服務(wù)分級(jí)存儲(chǔ)模型進(jìn)行深入解析,感興趣的朋友一起看看吧
    2024-02-02
  • Spring學(xué)習(xí)教程之AOP模塊的概述

    Spring學(xué)習(xí)教程之AOP模塊的概述

    AOP 從功能的角度來講,可能看作OOP編程方式的一種補(bǔ)充,提供了一種不同的代碼或者系統(tǒng)組織方式,下面這篇文章主要給大家介紹了關(guān)于Spring學(xué)習(xí)教程之AOP模塊的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05
  • java 同步器SynchronousQueue詳解及實(shí)例

    java 同步器SynchronousQueue詳解及實(shí)例

    這篇文章主要介紹了java 同步器SynchronousQueue詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java 中圖片壓縮處理的解決方案

    Java 中圖片壓縮處理的解決方案

    圖片經(jīng)過base64編碼轉(zhuǎn)換后,文件會(huì)變大的原因是因?yàn)閎ase64編碼會(huì)將每個(gè)3字節(jié)的數(shù)據(jù)轉(zhuǎn)換成4字節(jié)的數(shù)據(jù),并且在轉(zhuǎn)換的過程中還會(huì)添加一些額外的字符,這篇文章主要介紹了Java 中如何對(duì)圖片進(jìn)行壓縮處理,需要的朋友可以參考下
    2023-09-09
  • SpringBoot應(yīng)用快速部署到K8S的詳細(xì)教程

    SpringBoot應(yīng)用快速部署到K8S的詳細(xì)教程

    這篇文章主要介紹了SpringBoot應(yīng)用快速部署到K8S的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 淺談Java線程間通信之wait/notify

    淺談Java線程間通信之wait/notify

    下面小編就為大家?guī)硪黄獪\談Java線程間通信之wait/notify。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • SpringBoot使用SensitiveWord實(shí)現(xiàn)敏感詞過濾

    SpringBoot使用SensitiveWord實(shí)現(xiàn)敏感詞過濾

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何使用SensitiveWord實(shí)現(xiàn)敏感詞過濾功能,文中示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-01-01
  • Spring將MultipartFile轉(zhuǎn)存到本地磁盤的三種方式

    Spring將MultipartFile轉(zhuǎn)存到本地磁盤的三種方式

    在Java中處理文件向來是一種不是很方便的操作,然后隨著Spring框架的崛起,使用Spring框架中的MultipartFile來處理文件也是件很方便的事了,今天就給大家介紹Spring將MultipartFile轉(zhuǎn)存到本地磁盤的方式,需要的朋友可以參考下
    2024-10-10
  • 關(guān)于Netty--Http請(qǐng)求處理方式

    關(guān)于Netty--Http請(qǐng)求處理方式

    這篇文章主要介紹了關(guān)于Netty--Http請(qǐng)求處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評(píng)論

菏泽市| 石首市| 香港 | 安塞县| 青海省| 汉阴县| 富阳市| 济宁市| 哈密市| 斗六市| 巩留县| 荔波县| 凤冈县| 诏安县| 米易县| 聊城市| 富民县| 太仓市| 望奎县| 塔河县| 德安县| 邵阳市| 贵南县| 宁晋县| 乌兰浩特市| 鹤岗市| 明水县| 务川| 历史| 咸宁市| 永泰县| 平原县| 三江| 界首市| 乃东县| 来宾市| 杭州市| 辉县市| 舟山市| 团风县| 上蔡县|