SpringBoot文件上传接口设计指南

文件上传接口设计

文件上传功能通常涉及前端传递文件数据到后端,后端接收并存储文件。设计时需考虑文件大小限制、文件类型校验、存储位置以及安全性。

接口路径: /api/upload 请求方法: POST 请求头: Content-Type: multipart/form-data 请求参数:

  • file: 文件数据(必填)
  • uploadPath: 文件存储路径(可选,默认值由后端配置)

响应格式:

{
  "success": boolean,
  "message": string,
  "data": {
    "fileName": string,
    "filePath": string,
    "fileSize": number
  }
}

后端实现(Spring Boot)

使用Spring Boot框架实现文件上传接口,主要依赖spring-boot-starter-web

依赖配置:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

控制器代码:

@RestController
@RequestMapping("/api")
public class FileUploadController {

  @Value("${file.upload-dir}")
  private String uploadDir;

  @PostMapping("/upload")
  public ResponseEntity<Map<String, Object>> uploadFile(
      @RequestParam("file") MultipartFile file,
      @RequestParam(value = "uploadPath", required = false) String uploadPath) {

    Map<String, Object> response = new HashMap<>();
    
    try {
      String fileName = StringUtils.cleanPath(file.getOriginalFilename());
      Path directory = Paths.get(uploadDir, uploadPath != null ? uploadPath : "");
      Files.createDirectories(directory);
      Path filePath = directory.resolve(fileName);

      Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);

      response.put("success", true);
      response.put("message", "File uploaded successfully");
      response.put("data", Map.of(
          "fileName", fileName,
          "filePath", filePath.toString(),
          "fileSize", file.getSize()
      ));
      return ResponseEntity.ok(response);
    } catch (Exception e) {
      response.put("success", false);
      response.put("message", "Failed to upload file: " + e.getMessage());
      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
  }
}

配置文件:

# application.properties
file.upload-dir=uploads
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

前端实现(HTML + JavaScript)

前端通过表单提交文件数据,使用FormData对象包装文件。

HTML表单:

<form id="uploadForm" enctype="multipart/form-data">
  <input type="file" name="file" id="fileInput">
  <input type="text" name="uploadPath" placeholder="Optional storage path">
  <button type="submit">Upload</button>
</form>
<div id="result"></div>

JavaScript代码:

document.getElementById('uploadForm').addEventListener('submit', async (e) => {
  e.preventDefault();
  const formData = new FormData();
  const fileInput = document.getElementById('fileInput');
  const uploadPath = e.target.elements.uploadPath.value;

  formData.append('file', fileInput.files[0]);
  if (uploadPath) formData.append('uploadPath', uploadPath);

  try {
    const response = await fetch('/api/upload', {
      method: 'POST',
      body: formData
    });
    const result = await response.json();
    document.getElementById('result').innerHTML = JSON.stringify(result, null, 2);
  } catch (error) {
    console.error('Upload failed:', error);
  }
});

安全性增强

文件类型校验: 在控制器中添加校验逻辑,避免上传恶意文件。

String contentType = file.getContentType();
if (!Arrays.asList("image/jpeg", "image/png").contains(contentType)) {
  response.put("success", false);
  response.put("message", "Only JPEG/PNG files are allowed");
  return ResponseEntity.badRequest().body(response);
}

文件名处理: 避免路径遍历攻击,确保文件名安全。

String fileName = file.getOriginalFilename();
if (fileName.contains("..")) {
  response.put("success", false);
  response.put("message", "Invalid file name");
  return ResponseEntity.badRequest().body(response);
}

存储优化

分块上传: 大文件可采用分块上传,减少内存占用。

@PostMapping("/upload-chunk")
public ResponseEntity<?> uploadChunk(
    @RequestParam("chunk") MultipartFile chunk,
    @RequestParam("chunkNumber") int chunkNumber,
    @RequestParam("totalChunks") int totalChunks,
    @RequestParam("identifier") String identifier) {
  // 实现分块合并逻辑
}

云存储集成: 可扩展为AWS S3或阿里云OSS存储。

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();
s3Client.putObject("bucket-name", "file-key", file.getInputStream(), null);

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值