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

SpringBoot實(shí)現(xiàn)項(xiàng)目文件上傳的方法詳解

 更新時(shí)間:2022年11月23日 10:09:20   作者:狐貍與小兔的故事  
這篇文章主要為大家詳細(xì)介紹了SpringBoot中實(shí)現(xiàn)項(xiàng)目文件上傳的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下

一、首先拋出問題

以阿里云oss文件上傳為例,假設(shè)我的需求是這樣的,我需要發(fā)布一條動(dòng)態(tài),這條動(dòng)態(tài)呢可以是圖片、語音、視頻,3種類型,每種類型的上傳我必須要限制它的文件大小,超過了我就不能讓他上傳的。如果傳統(tǒng)的方式,那就是創(chuàng)建3個(gè)上傳類型bucket對(duì)應(yīng)圖片、語音和視頻,其實(shí)這種做法是可以的,但是怎么說呢,還不夠優(yōu)雅,如果當(dāng)這個(gè)動(dòng)態(tài)有越來越多種類型,你是不是要建立N個(gè)類型對(duì)應(yīng)呢,所以就會(huì)使得bucket特別的多,不好維護(hù)。

二、解決思路

首先,我們可以區(qū)分bucket的上傳類型大類,比如動(dòng)態(tài)是一個(gè)大類,它的子類呢有:圖片、語音、視頻,3種,每種的上傳文件大小的限制是不一樣的。文件上傳后的位置統(tǒng)一都是放到大類bucketName文件夾上。我們可以建立一個(gè)枚舉類,該枚舉類比較特殊,是存儲(chǔ)子分類數(shù)組的。code就是大分類,value是子分類數(shù)組。

三、直接看源碼就懂了,下面是controller

@ApiOperation(value = "上傳文件", notes = "bucketName選擇[avatar(頭像),file(文件),banner,game(游戲),dynamic(動(dòng)態(tài)),room_bg_img(房間背景圖)],文件上傳按分類管理,其他類型請(qǐng)通知添加")
@PostMapping("/uploadFile")
public ResponseResult<UploadFileDto> uploadFile(@RequestParam MultipartFile file, @RequestParam String bucketName) {
    ResponseResult responseResult = ResponseResult.error();
    Entry entry = null;
    try {
        //限流
        entry = SphU.entry("uploadFile", EntryType.IN, 1, SessionUtil.getUserId());
        //驗(yàn)證是否是可上傳的分類
        if (!BucketNameLimitSizeEnum.isValidEnum(bucketName)) {
            responseResult.setError(ResponseMessage.BUCKET_NAME_NOT_EXIST);
            return responseResult;
        }
        //獲取文件限制大小
        FileLimitItem[] items = BucketNameLimitSizeEnum.getLimitItemByCode(bucketName);
        //判斷文件屬于什么類型
        Integer typeNum = FileTypeUtil.getContentType(file.getOriginalFilename());

        //判斷該上傳類型是哪種類型,并判斷是否超過限制
        for (FileLimitItem item : items){
            if (typeNum == item.getType()){
                if (!MultipartFileUtil.checkFileSize(file.getSize(),item.getNum(),"K")){
                    responseResult.setError(ResponseMessage.FILE_SIZE_BIG);
                    return responseResult;
                }
                break;
            }
        }
        UploadFile entity = uploadFileService.upload(file, bucketName);
        UploadFileDto uploadFileDto = new UploadFileDto();
        BeanUtils.copyProperties(entity,uploadFileDto);
        responseResult = ResponseResult.success(uploadFileDto);
    }catch (BlockException e1) {
        /* 流控邏輯處理 - 開始 */
        log.warn("上傳文件限流!");
        return ResponseResult.error(ResponseMessage.SENTINEL_ERROR);
        /* 流控邏輯處理 - 結(jié)束 */
    }catch (ApiException apiException){
        return ResponseResult.error(apiException.getResponseMessage());
    }catch (Exception e) {
        responseResult.setMessage(e.getMessage());
        log.error("上傳文件異常",e);
    }finally {
        if (entry != null) {
            entry.exit();
        }
    }
    return responseResult;
}

大分類枚舉類

/**
 * @Author huanxinLee
 * @Date 2021/10/18 20:25
 * @description : 單位 KB
 */
public enum BucketNameLimitSizeEnum {
    AVATAR("avatar",new FileLimitItem[]{FileLimitItem.genImageItem(300)}), // 頭像
    SCREENSHOTS("screenshots",new FileLimitItem[]{FileLimitItem.genImageItem(1536)}),//截屏,1.5M * 1024 = 1536KB
    ACTIVITY_IMG("activity_img",new FileLimitItem[]{FileLimitItem.genImageItem(1536)}),//活動(dòng)類圖片,1.5M * 1024 = 1536KB
    FILE("file",new FileLimitItem[]{FileLimitItem.genFileItem(20 * 1024)}), // 文件,20M
    BANNER("banner",new FileLimitItem[]{FileLimitItem.genImageItem(1536)}), // banner,1.5M
    GAME("game",new FileLimitItem[]{FileLimitItem.genFileItem(20 * 1024)}), // 游戲
    DYNAMIC("dynamic",new FileLimitItem[]{FileLimitItem.genImageItem(1536),FileLimitItem.genAudioItem(10 * 1024),FileLimitItem.genVideoItem(20 * 1024)}),//動(dòng)態(tài)
    USER_REPORT("user_report",new FileLimitItem[]{FileLimitItem.genFileItem(20 * 1024)}), // 舉報(bào)個(gè)人
    ;

    private String code;
    private FileLimitItem[] limitItems;

    BucketNameLimitSizeEnum(String code, FileLimitItem[] limitItems) {
        this.code = code;
        this.limitItems = limitItems;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public FileLimitItem[] getLimitItems() {
        return limitItems;
    }

    public void setLimitItems(FileLimitItem[] limitItems) {
        this.limitItems = limitItems;
    }

    //通過code獲取限制大小數(shù)組
    public static FileLimitItem[] getLimitItemByCode(String code){
        for (BucketNameLimitSizeEnum bucketNameLimitSizeEnum : BucketNameLimitSizeEnum.values()){
            if (bucketNameLimitSizeEnum.getCode().equals(code)) {
                return bucketNameLimitSizeEnum.getLimitItems();
            }
        }
        return null;
    }

    //判斷是否存在該上傳類
    public static boolean isValidEnum(String code) {
        for (BucketNameLimitSizeEnum typeEnum : BucketNameLimitSizeEnum.values()) {
            if (typeEnum.getCode().equals(code)) {
                return true;
            }
        }
        return false;
    }
}

枚舉子分類數(shù)組,主要把所有上傳的類型分為4大類:圖片、音頻、視頻、文件

/**
 * @Author huanxinLee
 * @Date 2021/10/18 21:08
 * @description : 文件上傳 分類
 */
public class FileLimitItem {

    public static final int TYPE_IMAGE = 1;//圖片
    public static final int TYPE_AUDIO = 2;//音頻
    public static final int TYPE_VIDEO = 3;//視頻
    public static final int TYPE_FILE = 4;//文件

    private int type;
    private int num;

    FileLimitItem() {
    }

    FileLimitItem(int type, int num) {
        this.type = type;
        this.num = num;
    }

    // image
    public static FileLimitItem genImageItem(int num){
        return new FileLimitItem(TYPE_IMAGE,num);
    }

    // audio
    public static FileLimitItem genAudioItem(int num){
        return new FileLimitItem(TYPE_AUDIO,num);
    }

    // video
    public static FileLimitItem genVideoItem(int num){
        return new FileLimitItem(TYPE_VIDEO,num);
    }

    // file
    public static FileLimitItem genFileItem(int num){
        return new FileLimitItem(TYPE_FILE,num);
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

判斷文件大小是否超的工具類

/**
 * @Author huanxinLee
 * @Date 2021/10/18 20:44
 * @description : 文件上傳限制大小工具類
 */
public class MultipartFileUtil {

    /**
     * @param len  文件長(zhǎng)度
     * @param size 限制大小
     * @param unit 限制單位(B,K,M,G)
     * @描述 判斷文件大小
     */
    public static boolean checkFileSize(Long len, int size, String unit) {
        double fileSize = 0;
        if ("B".equalsIgnoreCase(unit)) {
            fileSize = (double) len;
        } else if ("K".equalsIgnoreCase(unit)) {
            fileSize = (double) len / 1024;
        } else if ("M".equalsIgnoreCase(unit)) {
            fileSize = (double) len / 1048576;
        } else if ("G".equalsIgnoreCase(unit)) {
            fileSize = (double) len / 1073741824;
        }
        return !(fileSize > size);
    }

    /**
     * file轉(zhuǎn)multipartFile
     */
    public static MultipartFile fileToMultipartFile(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item=factory.createItem(file.getName(),"text/plain",true,file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new CommonsMultipartFile(item);
    }

    /**
     * inputStream 轉(zhuǎn) File
     */
    public static File inputStreamToFile(InputStream ins, String name) throws Exception{
        //System.getProperty("java.io.tmpdir")臨時(shí)目錄+File.separator目錄中間的間隔符+文件名
        File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
//        if (file.exists()) {
//            return file;
//        }
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        int len = 8192;
        byte[] buffer = new byte[len];
        while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;
    }
}

四、結(jié)尾

優(yōu)雅的文件上傳其實(shí)只要認(rèn)真看了我上面的代碼,就懂得了。主要是大枚舉內(nèi)存的是數(shù)組類,這種寫法比較少見,但是卻能解決多種不同類型文字限制大小的代碼拓展性。

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)項(xiàng)目文件上傳的方法詳解的文章就介紹到這了,更多相關(guān)SpringBoot文件上傳內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaWeb中的組件Filter過濾器解析

    JavaWeb中的組件Filter過濾器解析

    這篇文章主要介紹了JavaWeb中的組件Filter過濾器解析,Filter過濾器是一種用于處理和轉(zhuǎn)換數(shù)據(jù)的工具,常用于Web開發(fā)中,它可以在請(qǐng)求到達(dá)服務(wù)器之前或響應(yīng)返回給客戶端之前對(duì)數(shù)據(jù)進(jìn)行預(yù)處理或后處理,需要的朋友可以參考下
    2023-10-10
  • 微信公眾號(hào)模板消息接口開發(fā)Java實(shí)現(xiàn)方法代碼

    微信公眾號(hào)模板消息接口開發(fā)Java實(shí)現(xiàn)方法代碼

    這篇文章主要介紹了微信公眾號(hào)模板消息接口開發(fā)Java實(shí)現(xiàn)的相關(guān)資料,,該接口可以用于向關(guān)注公眾號(hào)的用戶推送消息,包括群發(fā)和指定用戶發(fā)送消息,文章詳細(xì)介紹了如何獲取公眾號(hào)的測(cè)試信息、配置接口信息和獲取access_token,需要的朋友可以參考下
    2024-12-12
  • Java基于對(duì)象流實(shí)現(xiàn)銀行系統(tǒng)

    Java基于對(duì)象流實(shí)現(xiàn)銀行系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java基于對(duì)象流實(shí)現(xiàn)銀行系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • java對(duì)象與json對(duì)象之間互相轉(zhuǎn)換實(shí)現(xiàn)方法示例

    java對(duì)象與json對(duì)象之間互相轉(zhuǎn)換實(shí)現(xiàn)方法示例

    這篇文章主要介紹了java對(duì)象與json對(duì)象之間互相轉(zhuǎn)換實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了java對(duì)象與json對(duì)象相互轉(zhuǎn)換實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • Java實(shí)現(xiàn)跳躍表(skiplist)的簡(jiǎn)單實(shí)例

    Java實(shí)現(xiàn)跳躍表(skiplist)的簡(jiǎn)單實(shí)例

    這篇文章主要介紹了Java編程中跳躍表的概念和實(shí)現(xiàn)原理,并簡(jiǎn)要敘述了它的結(jié)構(gòu),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • Spring Boot的filter(過濾器)簡(jiǎn)單使用實(shí)例詳解

    Spring Boot的filter(過濾器)簡(jiǎn)單使用實(shí)例詳解

    過濾器(Filter)的注冊(cè)方法和 Servlet 一樣,有兩種方式:代碼注冊(cè)或者注解注冊(cè),下面通過實(shí)例給大家介紹Spring Boot的filter(過濾器)簡(jiǎn)單使用,一起看看吧
    2017-04-04
  • java將一個(gè)目錄下的所有數(shù)據(jù)復(fù)制到另一個(gè)目錄下

    java將一個(gè)目錄下的所有數(shù)據(jù)復(fù)制到另一個(gè)目錄下

    這篇文章主要為大家詳細(xì)介紹了java將一個(gè)目錄下的所有數(shù)據(jù)復(fù)制到另一個(gè)目錄下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 為什么Spring官方推薦的@Transational還能導(dǎo)致生產(chǎn)事故

    為什么Spring官方推薦的@Transational還能導(dǎo)致生產(chǎn)事故

    在Spring中進(jìn)行事務(wù)管理非常簡(jiǎn)單,只需要在方法上加上注解@Transactional,那么為什么Spring官方推薦的@Transational還能導(dǎo)致生產(chǎn)事故,本文就詳細(xì)的介紹一下
    2021-11-11
  • 分析Java中Map的遍歷性能問題

    分析Java中Map的遍歷性能問題

    隨著JDK 1.8 Streams API的發(fā)布,使得HashMap擁有了更多的遍歷的方式,但應(yīng)該選擇那種遍歷方式?反而成了一個(gè)問題。本文從幾個(gè)方面來分析 HashMap各種遍歷方式的優(yōu)勢(shì)與不足
    2021-06-06
  • MyBatis中resultType和parameterType和resultMap使用總結(jié)

    MyBatis中resultType和parameterType和resultMap使用總結(jié)

    這篇文章主要介紹了MyBatis中resultType和parameterType和resultMap使用總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評(píng)論

比如县| 新源县| 太和县| 天全县| 大厂| 定日县| 夏邑县| 清原| 武汉市| 唐河县| 呼玛县| 乾安县| 嵊州市| 化德县| 隆安县| 仁化县| 高密市| 十堰市| 潮安县| 通渭县| 旬邑县| 荔浦县| 开阳县| 宝应县| 南部县| 陆河县| 青岛市| 达拉特旗| 荔浦县| 驻马店市| 临安市| 壤塘县| 吉木乃县| 朝阳县| 招远市| 茂名市| 衡山县| 上思县| 宝兴县| 桃园市| 乡宁县|