首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java Web 文件上傳:獲取的是輸入流而非客戶端本地路徑

     編輯:程式設計疑難解答

核心誤區

前端 `` 選擇文件后,**瀏覽器出于安全考慮不會將客戶端絕對路徑傳給服務器**(現代瀏覽器僅傳文件名)。后端無法、也不應獲取客戶端本地路徑。

正確流程

  1. 前端 `
    ` 提交,文件以**二進制流**形式上傳。
  2. 后端 (Servlet/Spring MVC) 通過 `request.getPart("file")` 或 `MultipartFile` 獲取 **InputStream**。
  3. 服務器按業務規則保存文件(如 `/data/uploads/{uuid}.ext`),數據庫存**相對路徑/URL/元數據**。
  4. 下載/預覽時,后端讀取服務器文件流返回,設置 `Content-Type`、`Content-Disposition`。

Spring Boot 示例

@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
    if (file.isEmpty()) return "error";
    String original = file.getOriginalFilename();
    String ext = original.substring(original.lastIndexOf('.'));
    String storedName = UUID.randomUUID() + ext;
    Path dest = Paths.get(UPLOAD_ROOT, storedName);
    Files.copy(file.getInputStream(), dest, StandardCopyOption.REPLACE_EXISTING);
    // 存數據庫:originalName, storedName, size, contentType, uploadTime...
    return "success";
}

@GetMapping("/download/{storedName}")
public void download(@PathVariable String storedName, HttpServletResponse resp) throws IOException {
    Path file = Paths.get(UPLOAD_ROOT, storedName);
    if (!Files.exists(file)) { resp.sendError(404); return; }
    resp.setContentType(Files.probeContentType(file));
    resp.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(storedName, "UTF-8") + "\"");
    Files.copy(file, resp.getOutputStream());
}

關鍵點

  • **永不信任客戶端路徑**——它不可攜、不可預測、有安全風險。
  • 文件存儲與 Web 根目錄隔離,防止直接 URL 訪問繞過權限。
  • 大文件採用分片上傳、斷點續傳(Plupload、WebUploader、Tus 協議)。

總結

文件上傳的本質是**流傳輸 + 服務器落盤 + 元數據入庫**。忘掉客戶端路徑,擁抱流式處理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved