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

Spring?Boot?處理帶文件表單的方式匯總

 更新時間:2025年12月12日 11:54:51   作者:zwjapple  
本文詳細介紹了六種處理文件上傳的方式,包括@RequestParam、@RequestPart、@ModelAttribute、@ModelAttribute+@RequestPart、@RequestPart接收JSON和HttpServletRequest原生方式,每種方式都有其特點和適用場景,感興趣的朋友跟隨小編一起看看吧

方式 1:@RequestParam接收文件

后端代碼

@PostMapping("/upload1")
public Result upload1(
    @RequestParam("file") MultipartFile file,
    @RequestParam("name") String name,
    @RequestParam("age") Integer age
) {
    // 處理文件
    String filename = file.getOriginalFilename();
    long size = file.getSize();
    return Result.success();
}

前端代碼

const formData = new FormData();
formData.append('file', fileBlob);
formData.append('name', 'John');
formData.append('age', '25');
fetch('/api/upload1', {
    method: 'POST',
    body: formData
});

特點

  • ? 最簡單直接
  • ? 適合少量參數(shù)
  • ? 參數(shù)多時代碼冗長
  • ? 無法使用 @Valid 統(tǒng)一驗證

方式 2:@RequestPart接收文件

后端代碼

@PostMapping("/upload2")
public Result upload2(
    @RequestPart("file") MultipartFile file,
    @RequestPart("name") String name,
    @RequestPart("age") Integer age
) {
    return Result.success();
}

前端代碼

// 與方式1相同
const formData = new FormData();
formData.append('file', fileBlob);
formData.append('name', 'John');
formData.append('age', '25');

特點

  • ? 語義更明確(專為 multipart 設計)
  • ? 可以指定每個 part 的 Content-Type
  • ? 與 @RequestParam 功能類似,參數(shù)多時也冗長

方式 3:@ModelAttribute接收(文件在 DTO 中)

后端代碼

@Data
public class UploadDTO {
    @NotNull(message = "文件不能為空")
    private MultipartFile file;
    @NotBlank(message = "姓名不能為空")
    private String name;
    @NotNull(message = "年齡不能為空")
    @Min(value = 0, message = "年齡不能為負數(shù)")
    private Integer age;
    private String description;
}
@PostMapping("/upload3")
public Result upload3(@Valid @ModelAttribute UploadDTO dto) {
    MultipartFile file = dto.getFile();
    // 額外檢查文件是否為空
    if (file.isEmpty()) {
        throw new BusinessException("文件內(nèi)容不能為空");
    }
    return Result.success();
}

前端代碼

const formData = new FormData();
formData.append('file', fileBlob);
formData.append('name', 'John');
formData.append('age', '25');
formData.append('description', '這是描述');
fetch('/api/upload3', {
    method: 'POST',
    body: formData
});

特點

  • ? 代碼簡潔,參數(shù)封裝在 DTO 中
  • ? 支持 @Valid 統(tǒng)一驗證
  • ? DTO 可復用
  • ? 適合傳統(tǒng)表單提交
  • ? 只支持扁平數(shù)據(jù)結構

方式 4:@ModelAttribute+@RequestPart混合(推薦)

后端代碼

@Data
public class LoanRequest {
    @NotBlank(message = "姓名不能為空")
    private String name;
    @NotNull(message = "貸款金額不能為空")
    private BigDecimal amount;
    @NotBlank(message = "貸款類型不能為空")
    private String loanType;
    private String description;
}
@PostMapping("/upload4")
public Result upload4(
    @Valid @ModelAttribute LoanRequest request,
    @RequestPart(value = "propProofDocs", required = false) MultipartFile file
) {
    // 文件驗證
    if (file == null || file.isEmpty()) {
        throw new BusinessException("財產(chǎn)證明文件不能為空");
    }
    return Result.success();
}

前端代碼

const formData = new FormData();
// 普通字段
formData.append('name', 'John');
formData.append('amount', '100000');
formData.append('loanType', 'mortgage');
formData.append('description', '購房貸款');
// 文件單獨處理
formData.append('propProofDocs', fileBlob);
fetch('/api/upload4', {
    method: 'POST',
    body: formData
});

特點

  • ? 最靈活,業(yè)務數(shù)據(jù)和文件分離
  • ? 支持 DTO 驗證
  • ? 文件驗證可以單獨處理
  • ? 適合復雜業(yè)務場景
  • ? 推薦用于大多數(shù)項目

方式 5:@RequestPart接收 JSON + 文件

后端代碼

@Data
public class UserInfo {
    @NotBlank(message = "姓名不能為空")
    private String name;
    @NotNull(message = "年齡不能為空")
    private Integer age;
    private List<String> hobbies;  // 支持復雜結構
    private Address address;  // 支持嵌套對象
}
@Data
class Address {
    private String city;
    private String street;
}
@PostMapping("/upload5")
public Result upload5(
    @Valid @RequestPart("userInfo") UserInfo userInfo,
    @RequestPart("avatar") MultipartFile avatar
) {
    return Result.success();
}

前端代碼

const userInfo = {
    name: 'John',
    age: 25,
    hobbies: ['reading', 'coding'],
    address: {
        city: 'Beijing',
        street: 'Chang\'an Ave'
    }
};
const formData = new FormData();
// 將 JSON 對象轉(zhuǎn)為 Blob,指定 Content-Type
formData.append('userInfo', new Blob([JSON.stringify(userInfo)], {
    type: 'application/json'
}));
formData.append('avatar', fileBlob);
fetch('/api/upload5', {
    method: 'POST',
    body: formData
});

特點

  • ? 支持復雜 JSON 結構(數(shù)組、嵌套對象)
  • ? 前后端分離友好
  • ? RESTful 風格
  • ? 前端需要額外構造 JSON Blob
  • ? 推薦用于復雜數(shù)據(jù)結構

方式 6:多文件上傳

后端代碼

// 方式 6.1:數(shù)組接收
@PostMapping("/upload6-1")
public Result upload6(
    @RequestParam("files") MultipartFile[] files,
    @RequestParam("description") String description
) {
    for (MultipartFile file : files) {
        // 處理每個文件
    }
    return Result.success();
}
// 方式 6.2:List 接收
@PostMapping("/upload6-2")
public Result upload6(
    @RequestParam("files") List<MultipartFile> files,
    @RequestParam("description") String description
) {
    files.forEach(file -> {
        // 處理每個文件
    });
    return Result.success();
}
// 方式 6.3:不同字段多個文件
@PostMapping("/upload6-3")
public Result upload6(
    @RequestPart("idCard") MultipartFile idCard,
    @RequestPart("bankCard") MultipartFile bankCard,
    @RequestPart("propProof") MultipartFile propProof
) {
    return Result.success();
}

前端代碼

// 多個文件同名
const formData = new FormData();
files.forEach(file => {
    formData.append('files', file);  // 注意:相同的 key
});
formData.append('description', '批量上傳');
// 多個文件不同名
const formData2 = new FormData();
formData2.append('idCard', idCardFile);
formData2.append('bankCard', bankCardFile);
formData2.append('propProof', propProofFile);

方式 7:HttpServletRequest 原生方式

后端代碼

@PostMapping("/upload7")
public Result upload7(HttpServletRequest request) throws Exception {
    // 判斷是否為 multipart 請求
    if (!ServletFileUpload.isMultipartContent(request)) {
        throw new BusinessException("請求格式錯誤");
    }
    // 使用 Apache Commons FileUpload
    ServletFileUpload upload = new ServletFileUpload();
    List<FileItem> items = upload.parseRequest(new ServletRequestContext(request));
    for (FileItem item : items) {
        if (item.isFormField()) {
            // 普通字段
            String fieldName = item.getFieldName();
            String value = item.getString("UTF-8");
        } else {
            // 文件字段
            String filename = item.getName();
            InputStream inputStream = item.getInputStream();
            // 處理文件
        }
    }
    return Result.success();
}

特點

  • ? 完全控制
  • ? 適合特殊需求
  • ? 代碼復雜
  • ? 不推薦常規(guī)使用

完整對比表

方式適用場景代碼簡潔度驗證支持復雜結構推薦度
@RequestParam簡單場景,少量參數(shù)??????
@RequestPart與 @RequestParam 類似??????
@ModelAttribute(文件在DTO)傳統(tǒng)表單,扁平數(shù)據(jù)??????????
@ModelAttribute + @RequestPart通用場景????????????
@RequestPart (JSON)復雜JSON結構?????????
多文件上傳批量上傳?????????
HttpServletRequest特殊需求????

實際項目推薦

場景 1:簡單表單 + 單文件

@PostMapping("/simple")
public Result simple(
    @Valid @ModelAttribute SimpleDTO dto,
    @RequestPart("file") MultipartFile file
) { }

場景 2:復雜業(yè)務數(shù)據(jù) + 多文件

@PostMapping("/complex")
public Result complex(
    @Valid @RequestPart("data") ComplexDTO data,  // JSON
    @RequestPart("idCard") MultipartFile idCard,
    @RequestPart("bankCard") MultipartFile bankCard
) { }

場景 3:可選文件 + 表單驗證

@PostMapping("/optional")
public Result optional(
    @Valid @ModelAttribute FormDTO form,
    @RequestPart(value = "attachment", required = false) MultipartFile file
) {
    if (file != null && !file.isEmpty()) {
        // 處理文件
    }
}

文件驗證最佳實踐

自定義驗證注解

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FileValidator.class)
public @interface ValidFile {
    String message() default "文件不合法";
    long maxSize() default 10 * 1024 * 1024;  // 10MB
    String[] allowedTypes() default {};  // {"image/jpeg", "image/png"}
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
// 驗證器
public class FileValidator implements ConstraintValidator<ValidFile, MultipartFile> {
    private long maxSize;
    private String[] allowedTypes;
    @Override
    public void initialize(ValidFile annotation) {
        this.maxSize = annotation.maxSize();
        this.allowedTypes = annotation.allowedTypes();
    }
    @Override
    public boolean isValid(MultipartFile file, ConstraintValidatorContext context) {
        if (file == null || file.isEmpty()) {
            return false;
        }
        // 檢查大小
        if (file.getSize() > maxSize) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(
                "文件大小不能超過 " + (maxSize / 1024 / 1024) + "MB"
            ).addConstraintViolation();
            return false;
        }
        // 檢查類型
        if (allowedTypes.length > 0) {
            String contentType = file.getContentType();
            boolean typeMatched = Arrays.asList(allowedTypes).contains(contentType);
            if (!typeMatched) {
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate(
                    "只支持以下文件類型: " + String.join(", ", allowedTypes)
                ).addConstraintViolation();
                return false;
            }
        }
        return true;
    }
}
// 使用
@PostMapping("/validated")
public Result validated(
    @Valid @ModelAttribute FormDTO form,
    @ValidFile(
        maxSize = 5 * 1024 * 1024,  // 5MB
        allowedTypes = {"image/jpeg", "image/png", "application/pdf"},
        message = "文件不符合要求"
    )
    @RequestPart("file") MultipartFile file
) {
    return Result.success();
}

總結

日常開發(fā)推薦

  • ?? 方式 4@ModelAttribute + @RequestPart)- 最靈活通用
  • ?? 方式 3@ModelAttribute 包含文件)- 簡單場景
  • ?? 方式 5@RequestPart JSON)- 復雜數(shù)據(jù)結構

根據(jù)實際業(yè)務需求選擇合適的方式,優(yōu)先考慮代碼的可維護性和可讀性!

到此這篇關于Spring Boot 處理帶文件表單的方式匯總的文章就介紹到這了,更多相關springboot文件表單內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 基于RocketMQ實現(xiàn)分布式事務的方法

    基于RocketMQ實現(xiàn)分布式事務的方法

    了保證系統(tǒng)數(shù)據(jù)的一致性,我們需要確保這些服務中的操作要么全部成功,要么全部失敗,通過使用RocketMQ實現(xiàn)分布式事務,我們可以協(xié)調(diào)這些服務的操作,保證數(shù)據(jù)的一致性,這篇文章主要介紹了基于RocketMQ實現(xiàn)分布式事務,需要的朋友可以參考下
    2024-03-03
  • Spring Boot整合Spring Cache及Redis過程解析

    Spring Boot整合Spring Cache及Redis過程解析

    這篇文章主要介紹了Spring Boot整合Spring Cache及Redis過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • SpringBoot條件注解之@ConditionalOnClass等注解的使用場景分析

    SpringBoot條件注解之@ConditionalOnClass等注解的使用場景分析

    文章詳細介紹了SpringBoot中條件注解的體系,包括基本概念、@ConditionalOnClass等常用注解的工作原理和使用場景,文章還探討了條件注解的組合使用、實戰(zhàn)應用以及最佳實踐,幫助開發(fā)者更好地理解和應用條件注解,實現(xiàn)更靈活和智能的應用配置,感興趣的朋友一起看看吧
    2025-03-03
  • 基于JDK動態(tài)代理原理解析

    基于JDK動態(tài)代理原理解析

    這篇文章主要介紹了基于JDK動態(tài)代理原理解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Spring Boot之AOP配自定義注解的最佳實踐過程

    Spring Boot之AOP配自定義注解的最佳實踐過程

    這篇文章主要給大家介紹了關于Spring Boot之AOP配自定義注解的最佳實踐過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11
  • Java如何獲取文件夾下所有壓縮包下指定文件

    Java如何獲取文件夾下所有壓縮包下指定文件

    在Java中,通過遍歷文件夾并對壓縮包進行解析,可以實現(xiàn)提取指定文件的功能,如文檔、PDF等,該過程中可增加過濾條件來適應不同需求,例如文件類型或文件名過濾,該方法適用于處理大量數(shù)據(jù)時的文件管理和數(shù)據(jù)提取
    2024-09-09
  • Spring Boot 使用 logback、logstash、ELK 記錄日志文件的方法

    Spring Boot 使用 logback、logstash、ELK 記錄日志文件的方法

    這篇文章主要介紹了Spring Boot 使用 logback、logstash、ELK 記錄日志文件的思路詳解,文中給大家提到了logback 取代 log4j的理由,需要的朋友可以參考下
    2017-12-12
  • Nacos1.4.0 Windows10單機模式啟動和集群啟動過程解析

    Nacos1.4.0 Windows10單機模式啟動和集群啟動過程解析

    這篇文章主要介紹了Nacos1.4.0 Windows10單機模式啟動和集群啟動,第一次使用nacos,廢話不多說,記錄下自己啟動Nacos遇到的坑,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • SpringBoot整合RabbitMQ消息隊列的完整步驟

    SpringBoot整合RabbitMQ消息隊列的完整步驟

    這篇文章主要給大家介紹了關于SpringBoot整合RabbitMQ消息隊列的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • SpringBoot循環(huán)依賴全場景解析與終極解決方案

    SpringBoot循環(huán)依賴全場景解析與終極解決方案

    這篇文章主要為大家詳細介紹了SpringBoot循環(huán)依賴全場景解析與終極解決方案,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-06-06

最新評論

洛隆县| 乌兰察布市| 垣曲县| 普定县| 马关县| 龙江县| 锦州市| 张掖市| 三都| 康定县| 天全县| 西盟| 西盟| 安庆市| 清水河县| 丁青县| 五大连池市| 乐清市| 永城市| 丰顺县| 开远市| 施甸县| 苏尼特左旗| 高邮市| 宁阳县| 三门县| 彰化县| 克东县| 澎湖县| 依安县| 灵武市| 临夏县| 吴桥县| 华坪县| 美姑县| 巢湖市| 平凉市| 汝城县| 巴林左旗| 财经| 旌德县|