hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Cấu trúc dữ liệu và giải thuật
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
      • NodeJS
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
      • MongoDB
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
      • Spring Boot
    • Lập trình C#
      • Lập Trình C# Cơ Bản
      • ASP.NET Core MVC
    • Lập trình Python
    • Git và Github
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
    • Mạng và truyền thông
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Spring Boot
Spring Boot bài 16: Upload và download tài liệu có giới hạn
Java và Spring Boot – MVC và REST API

Spring Boot bài 16: Upload và download tài liệu có giới hạn

  • 18-10-2026
  • Toanngo92
  • 0 Comments

Giáo trình Spring Boot MVC và REST API · Chương 7/12: Tìm kiếm, phân trang và tài liệu · Bài 16/28 · Biên soạn tháng 10/2026.

← Bài 15 · Mục lục 12 chương · Bài 17 →

Mục lục

  • Mục tiêu bài học
  • Thiết kế phạm vi nhỏ, rõ ràng
  • Tên file từ client không phải đường dẫn tin cậy
  • Download qua Controller
  • Lưu trữ và mở rộng
  • Lỗi thường gặp và lưu ý
  • Ghi nhớ
  • Tài liệu đối chiếu

Mục tiêu bài học

Nhận multipart, kiểm tra tệp và tải xuống qua endpoint được bảo vệ thay vì công khai thư mục upload.

Thiết kế phạm vi nhỏ, rõ ràng

Bài này chỉ nhận tệp .txt UTF-8 tối đa 1 MB tại /admin/files. Giới hạn loại tệp giúp tập trung vào luồng upload; không phải bộ xử lý ảnh, PDF hay bộ quét mã độc tổng quát. Chỉ teacher được tải lên hoặc tải xuống trong mẫu, vì tài liệu là tài nguyên quản trị.

Form cần method POST và enctype multipart/form-data. Input có name=file để khớp @RequestParam MultipartFile file. accept=.txt chỉ gợi ý cho hộp chọn tệp, không phải kiểm tra server. th:action giúp form nhận CSRF token giống các form POST khác.

<form th:action="@{/admin/files}" method="post" enctype="multipart/form-data">
  <input type="file" name="file" accept=".txt" required>
  <button>Tải lên</button>
</form>

Tên file từ client không phải đường dẫn tin cậy

Không ghép getOriginalFilename() vào thư mục lưu rồi ghi trực tiếp. Tên có thể chứa đường dẫn, ký tự lạ hoặc trùng với tệp hiện có. FileStore chỉ dùng tên gốc để kiểm tra đuôi, kiểm tra độ lớn, giải mã UTF-8 nghiêm ngặt, từ chối byte NUL rồi tạo tên UUID mới. MIME do client gửi không được xem là bằng chứng nội dung.

Thư mục hvc.upload-dir ở ngoài static và templates. Khi tải xuống, service chỉ chấp nhận mã UUID.txt và kiểm tra tệp thường, không đi theo symlink. Việc giới hạn đường dẫn phải thực hiện ở server dù URL download chỉ do chính ứng dụng sinh ra.

Tệp trong mã nguồn mẫu: src/main/java/com/hocvietcode/academy/FileStore.java. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.

public Path load(String id){
    if(!id.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[.]txt"))throw new IllegalArgumentException("Mã tệp không hợp lệ");
    Path path=root.resolve(id).normalize();
    if(!path.startsWith(root) || !Files.isRegularFile(path,LinkOption.NOFOLLOW_LINKS))throw new CourseNotFound();
    return path;
}

Download qua Controller

FileController trả Resource với Content-Disposition: attachment và kiểu text/plain; trình duyệt tải tài liệu thay vì tự coi nó là HTML. Mã file do server sinh được dùng làm tên tải về. Security tiếp tục kiểm tra teacher trên đường dẫn /admin/**.

Spring multipart đặt max-file-size=1MB và max-request-size=2MB; FileStore kiểm tra lại giới hạn nghiệp vụ. Tệp vượt giới hạn tầng multipart có thể bị chặn trước khi Controller chạy. Nếu xây sản phẩm, nên thêm trang báo lỗi dung lượng riêng, quota theo người dùng và cơ chế dọn tệp không còn được sử dụng.

Tệp trong mã nguồn mẫu: src/main/java/com/hocvietcode/academy/FileController.java. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.

@GetMapping("/admin/files/{id}") ResponseEntity<Resource> download(@PathVariable String id){
    Resource file=new FileSystemResource(files.load(id));
    return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN)
        .header(HttpHeaders.CONTENT_DISPOSITION,ContentDisposition.attachment().filename(id).build().toString())
        .header("X-Content-Type-Options","nosniff").body(file);
}

Lưu trữ và mở rộng

Upload vào ổ đĩa cục bộ chỉ phù hợp một instance hoặc volume được quản lý. Khi container bị thay thế, dữ liệu trong lớp ghi có thể mất; bài Docker sẽ gắn volume. Nhiều instance thường cần object storage hoặc hệ lưu trữ chung cùng metadata về chủ sở hữu và quyền truy cập.

Kiểm thử gồm tệp hợp lệ, tệp rỗng, quá dung lượng, sai đuôi, UTF-8 hỏng và mã chứa ../. Với ảnh/PDF, cần pipeline xác minh định dạng, giới hạn tài nguyên và chính sách bảo mật khác; không chỉ đổi danh sách đuôi trong ví dụ rồi coi là xử lý đầy đủ.

Lỗi thường gặp và lưu ý

  • Không lưu file người dùng dưới static để ai biết URL cũng truy cập được ngoài quy tắc quyền.
  • UUID tránh trùng tên, nhưng quyền download vẫn phải kiểm tra ở endpoint.

Ghi nhớ

Upload là một luồng dữ liệu và lưu trữ có giới hạn, tên do server quản lý và quyền truy cập được kiểm tra khi download.

Tài liệu đối chiếu

  • Multipart Forms

← Bài 15 · Mục lục 12 chương · Bài 17 →

Bài viết liên quan:

Java và Spring Boot – MVC và REST API
Spring Boot bài 19: CSRF, CORS và gọi API có session đúng cách
Java và Spring Boot – MVC và REST API
Spring Boot bài 20: REST Controller, JSON và DTO cho API danh sách
Java và Spring Boot – MVC và REST API
Spring Boot bài 21: REST CRUD: POST, PUT, DELETE và mã trạng thái
Java và Spring Boot – MVC và REST API
Spring Boot bài 22: Validation API, ProblemDetail và hợp đồng lỗi
Java và Spring Boot – MVC và REST API
Spring Boot bài 23: Gọi dịch vụ HTTP bằng RestClient và đặt timeout
Java và Spring Boot – MVC và REST API
Spring Boot bài 24: Gửi email và lập lịch tác vụ trong Spring Boot
Java và Spring Boot – MVC và REST API
Spring Boot bài 08: Fragment, layout và tài nguyên CSS trong Spring Boot
Java và Spring Boot – MVC và REST API
Spring Boot bài 25: Unit test Service với JUnit và Mockito
Java và Spring Boot – MVC và REST API
Spring Boot bài 09: Binding biểu mẫu tạo và sửa khóa học
Java và Spring Boot – MVC và REST API
Spring Boot bài 26: Integration test MVC, API, database và Security
Java và Spring Boot – MVC và REST API
Spring Boot bài 10: Validation và BindingResult: báo lỗi ngay trên biểu mẫu
Java và Spring Boot – MVC và REST API
Spring Boot bài 27: Logging, Actuator và quản lý schema bằng Flyway

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 05: Đơn vị và kích thước: px, rem, %, min và max

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 02: Selector và class: chọn đúng phần tử cần sửa

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 01: Kết nối CSS với HTML và sửa quy tắc đầu tiên

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 20: Hoàn thiện website và sửa lỗi bằng DevTools

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 03: Vì sao CSS không có tác dụng? Cascade và specificity

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×