File upload and download function is a common requirement in web applications. From simple user avatar upload to large files, a reliable file processing mechanism is required.
As a popular Java application development framework, SpringBoot provides a variety of tools and solutions to implement file upload and download.
This article will introduce seven tools to handle file upload and download in SpringBoot.
1. MultipartFile interface - basic file upload processing
SpringBoot built-inMultipartFile
Interface is a basic tool for handling file uploads, which is simple and easy to use and has complete functions.
Configuration method
existor
Configure the upload parameters:
spring: servlet: multipart: max-file-size: 10MB max-request-size: 10MB enabled: true
Example of usage
@RestController @RequestMapping("/api/files") public class FileUploadController { @PostMapping("/upload") public String uploadFile(@RequestParam("file") MultipartFile file) { if (()) { return "Please select the file to upload"; } try { // Get the file name String fileName = (); // Get file type String contentType = (); // Get the file content byte[] bytes = (); // Create storage path Path path = ("uploads/" + fileName); (()); // Save the file (path, bytes); return "File uploaded successfully: " + fileName; } catch (IOException e) { (); return "File upload failed: " + (); } } }
Advantages and applicable scenarios
Advantages
- SpringBoot native support, no additional dependencies required
- Simple configuration, API friendly
- Supports multiple file operation methods
Applicable scenarios
- Upload small to medium-sized files
- Basic file processing requirements
- Rapidly develop prototypes
2. Apache Commons FileUpload - Flexible file upload library
Although SpringBoot has integrated file upload functionality, in some scenarios, more advanced features provided by Apache Commons FileUpload may be required.
Configuration method
Add dependencies:
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.5</version> </dependency>
Configure Bean:
@Bean public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); ("UTF-8"); (10485760); // 10MB (2097152); // 2MB return resolver; }
Example of usage
@RestController @RequestMapping("/api/commons") public class CommonsFileUploadController { @PostMapping("/upload") public String handleFileUpload(HttpServletRequest request) throws Exception { // Determine whether the file is uploaded boolean isMultipart = (request); if (!isMultipart) { return "Not a valid file upload request"; } // Create an uploader DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); // parse request List<FileItem> items = (request); for (FileItem item : items) { if (!()) { // Process file items String fileName = (()); File uploadedFile = new File("uploads/" + fileName); (uploadedFile); return "File uploaded successfully: " + fileName; } } return "No file to upload was found"; } }
Advantages and applicable scenarios
Advantages
- Provides finer granular control
- Support file upload progress monitoring
- Customizable file storage policies
Applicable scenarios
- Fine-grained control of the upload process is required
- Upload large files and monitor progress
- Legacy system integration
3. Spring Resource Abstraction - Unified Resource Access
Spring'sResource
Abstraction provides a unified access method to resources from different sources, which is very suitable for file download scenarios.
Example of usage
@RestController @RequestMapping("/api/resources") public class ResourceDownloadController { @GetMapping("/download/{fileName:.+}") public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) { try { // Create file resources Path filePath = ("uploads/" + fileName); Resource resource = new UrlResource(()); // Check whether the resource exists if (()) { return () .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="" + () + """) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource); } else { return ().build(); } } catch (Exception e) { return ().build(); } } }
Advantages and applicable scenarios
Advantages
- Provides unified resource abstraction, easy to switch resource sources
- Seamless integration with Spring ecosystem
- Resources that support multiple protocols and locations
Applicable scenarios
- Scenarios that need to be provided from multiple sources
- RESTful API file download
- Dynamically generated resource downloads
4. ResponseEntity-based download response
In SpringBoot,ResponseEntity
Types can accurately control HTTP responses and provide complete HTTP header information for file downloads.
Example of usage
@RestController @RequestMapping("/api/download") public class FileDownloadController { @GetMapping("/file/{fileName:.+}") public ResponseEntity<byte[]> downloadFile(@PathVariable String fileName) { try { Path filePath = ("uploads/" + fileName); byte[] data = (filePath); HttpHeaders headers = new HttpHeaders(); (() .filename(fileName, StandardCharsets.UTF_8).build()); (MediaType.APPLICATION_OCTET_STREAM); (); return new ResponseEntity<>(data, headers, ); } catch (IOException e) { return ().build(); } } @GetMapping("/dynamic-pdf") public ResponseEntity<byte[]> generatePdf() { // Suppose here is a byte array of PDF files byte[] pdfContent = (); HttpHeaders headers = new HttpHeaders(); (() .filename("").build()); (MediaType.APPLICATION_PDF); return new ResponseEntity<>(pdfContent, headers, ); } }
Advantages and applicable scenarios
Advantages
- Full control of HTTP responses and header information
- Suitable for downloads of various resource types
- Support dynamically generated file downloads
Applicable scenarios
- Scenarios that require precise control of HTTP responses
- Dynamically generated file download
- File services for custom cache policies
5. Native file operations based on Servlet
In some cases, it may be necessary to use the native Servlet API for underlying file operations.
Example of usage
@WebServlet("/servlet/download") public class FileDownloadServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String fileName = ("file"); if (fileName == null || ()) { (HttpServletResponse.SC_BAD_REQUEST); return; } File file = new File("uploads/" + fileName); if (!()) { (HttpServletResponse.SC_NOT_FOUND); return; } // Set response header ("application/octet-stream"); ("Content-Disposition", "attachment; filename="" + fileName + """); ((int) ()); // Write file contents try (FileInputStream input = new FileInputStream(file); ServletOutputStream output = ()) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = (buffer)) != -1) { (buffer, 0, bytesRead); } } } }
To enable Servlet in SpringBoot:
@SpringBootApplication @ServletComponentScan // Scan the Servlet componentpublic class Application { public static void main(String[] args) { (, args); } }
Advantages and applicable scenarios
Advantages
- Have the greatest control over file flow operations
- Progressive download and streaming can be implemented
- More efficient use of memory
Applicable scenarios
- Large file processing
- IO operations need to be controlled in fine-grained manner
- Integrate with legacy Servlet systems
6. Cloud Storage Service SDK Integration
For production environments, storing files in professional storage services is usually a better choice, such as AWS S3, Alibaba Cloud OSS, Qiniu Cloud, etc.
Configuration method (taking Alibaba Cloud OSS as an example)
Add dependencies:
<dependency> <groupId></groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.15.1</version> </dependency>
Configure the client:
@Configuration public class OssConfig { @Value("${}") private String endpoint; @Value("${}") private String accessKeyId; @Value("${}") private String accessKeySecret; @Value("${}") private String bucketName; @Bean public OSS ossClient() { return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); } @Bean public String bucketName() { return bucketName; } }
Example of usage
@RestController @RequestMapping("/api/oss") public class OssFileController { @Autowired private OSS ossClient; @Value("${}") private String bucketName; @PostMapping("/upload") public String uploadToOss(@RequestParam("file") MultipartFile file) { if (()) { return "Please select a file"; } try { String fileName = ().toString() + "-" + (); // Upload file stream (bucketName, fileName, ()); // Generate access URL Date expiration = new Date(() + 3600 * 1000); URL url = (bucketName, fileName, expiration); return "File upload successfully, access URL: " + (); } catch (Exception e) { (); return "File upload failed: " + (); } } @GetMapping("/download") public ResponseEntity<byte[]> downloadFromOss(@RequestParam("key") String objectKey) { try { // Get the file OSSObject ossObject = (bucketName, objectKey); // Read file content try (InputStream is = ()) { byte[] content = (is); HttpHeaders headers = new HttpHeaders(); (MediaType.APPLICATION_OCTET_STREAM); (() .filename(objectKey).build()); return new ResponseEntity<>(content, headers, ); } } catch (Exception e) { (); return (HttpStatus.INTERNAL_SERVER_ERROR).build(); } } }
Advantages and applicable scenarios
Advantages
- High availability and scalability
- Built-in security mechanisms and access controls
- Relieve stress on application servers
Applicable scenarios
- File storage in production environment
- Scenarios that require high availability and CDN distribution
- Large-scale user uploaded applications
7. File type detection and verification based on Apache Tika
In a file upload scenario, ensuring file type safety is crucial. Apache Tika is a content analysis toolkit that accurately detects the real MIME type of a file, not only relying on file extensions, thereby improving application security.
Configuration method
Adding Apache Tika dependencies:
<dependency> <groupId></groupId> <artifactId>tika-core</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId></groupId> <artifactId>tika-parsers-standard-package</artifactId> <version>2.8.0</version> </dependency>
Example of usage
Create a file verification service:
@Service public class FileValidationService { private Tika tika = new Tika(); // Verify file type public boolean isValidFileType(MultipartFile file, List<String> allowedTypes) throws IOException { String detectedType = detectFileType(file); return ().anyMatch(type -> (type)); } // Detect file type public String detectFileType(MultipartFile file) throws IOException { try (InputStream is = ()) { return (is); } } // Extract file contents public String extractContent(MultipartFile file) throws IOException, TikaException, SAXException { try (InputStream is = ()) { return (is); } } // Extract file metadata public Metadata extractMetadata(MultipartFile file) throws IOException, TikaException, SAXException { Metadata metadata = new Metadata(); (Metadata.RESOURCE_NAME_KEY, ()); try (InputStream is = ()) { Parser parser = new AutoDetectParser(); ContentHandler handler = new DefaultHandler(); ParseContext context = new ParseContext(); (is, handler, metadata, context); return metadata; } } }
Secure file upload controller:
@RestController @RequestMapping("/api/secure-upload") public class SecureFileUploadController { @Autowired private FileValidationService fileValidationService; private static final List<String> ALLOWED_DOCUMENT_TYPES = ( "application/pdf", "application/msword", "application/", "application/-excel", "application/", "text/plain" ); private static final List<String> ALLOWED_IMAGE_TYPES = ( "image/jpeg", "image/png", "image/gif", "image/tiff" ); @PostMapping("/document") public ResponseEntity<Map<String, Object>> uploadDocument(@RequestParam("file") MultipartFile file) { Map<String, Object> response = new HashMap<>(); try { // Detect file type String detectedType = (file); ("detectedType", detectedType); // Verify file type if (!(file, ALLOWED_DOCUMENT_TYPES)) { ("success", false); ("message", "File type not allowed: " + detectedType); return ().body(response); } // Extract file content (depending on file type) String content = (file); ("contentPreview", () > 200 ? (0, 200) + "..." : content); // Extract metadata Metadata metadata = (file); Map<String, String> metadataMap = new HashMap<>(); (()).forEach(name -> (name, (name))); ("metadata", metadataMap); // Save the file String fileName = ().toString() + "-" + (); Path path = ("secure-uploads/" + fileName); (()); (path, ()); ("success", true); ("message", "File upload successfully"); ("filename", fileName); return (response); } catch (Exception e) { ("success", false); ("message", "File processing failed: " + ()); return (HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } @PostMapping("/image") public ResponseEntity<Map<String, Object>> uploadImage(@RequestParam("file") MultipartFile file) { Map<String, Object> response = new HashMap<>(); try { // Detect file type String detectedType = (file); ("detectedType", detectedType); // Verify file type if (!(file, ALLOWED_IMAGE_TYPES)) { ("success", false); ("message", "Image type not allowed: " + detectedType); return ().body(response); } // Extract metadata (picture information) Metadata metadata = (file); Map<String, String> metadataMap = new HashMap<>(); (()).forEach(name -> (name, (name))); ("metadata", metadataMap); // Get the image size if ((Metadata.IMAGE_WIDTH) != null && (Metadata.IMAGE_LENGTH) != null) { ("width", (Metadata.IMAGE_WIDTH)); ("height", (Metadata.IMAGE_LENGTH)); } // Save the file String fileName = ().toString() + "-" + (); Path path = ("secure-uploads/images/" + fileName); (()); (path, ()); ("success", true); ("message", "Picture upload successfully"); ("filename", fileName); return (response); } catch (Exception e) { ("success", false); ("message", "Image processing failed: " + ()); return (HttpStatus.INTERNAL_SERVER_ERROR).body(response); } } }
Advantages and applicable scenarios
Advantages
- Provides accurate file type detection, not only relying on extensions
- Prevent malicious file uploads and enhance application security
- Ability to extract file content and metadata
- Supports identification and content analysis of multiple file formats
Applicable scenarios
- File upload system that requires high security requirements
- Content management system and document management system
- Scenarios where malicious file uploads need to be prevented
Applications that require automatic classification or processing based on file content
Summarize
No matter which solution you choose, the file processing system should be designed based on the specific needs of the application, the expected number of users and the file size.
In most production environments, it is recommended to use a dedicated file storage service as the main storage solution, combining other tools to provide a better user experience.
The above is the detailed content of 7 methods for SpringBoot to upload and download files. For more information about SpringBoot file upload and download, please follow my other related articles!