All guides

How to Upload a PDF File Using Java

Handling file uploads is a common requirement in modern applications. This article will guide you through the process of uploading PDF files using Java, covering two primary scenarios: a basic Java application and a Spring Boot web service.

Prerequisites

  • Basic knowledge of Java.
  • Java Development Kit (JDK) 8 or later installed.
  • An IDE (like IntelliJ IDEA, Eclipse, or VS Code).
  • For the web example, basic familiarity with Spring Boot is helpful.

Method 1: Basic File Upload using java.nio (Console Application)

This method is perfect for simple operations, like copying a PDF from one location to another on the same machine or server. It uses the modern java.nio.file package, which is more robust and feature-rich than the legacy java.io package.

Steps:

  1. Import Necessary Classes:

    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.nio.file.StandardCopyOption;
    
  2. Define Source and Target Paths:

    • Source Path: The location of the PDF you want to upload.
    • Target Directory: The directory where you want to save the uploaded PDF.
  3. Copy the File: Use Files.copy() to perform the operation. The StandardCopyOption.REPLACE_EXISTING option ensures that if a file with the same name already exists in the target directory, it will be overwritten.

Complete Code Example:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class BasicPdfUpload {

    public static void main(String[] args) {
        // Path to the source PDF file
        Path sourcePath = Paths.get("C:/Users/User/Downloads/sample.pdf");

        // Path to the target upload directory
        Path targetDir = Paths.get("C:/uploads");

        // Resolve the target file path (keeps the original filename)
        Path targetPath = targetDir.resolve(sourcePath.getFileName());

        try {
            // Create the target directory if it doesn't exist
            Files.createDirectories(targetDir);

            // Copy the file from source to target
            Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);

            System.out.println("PDF uploaded successfully to: " + targetPath.toString());

        } catch (IOException e) {
            System.err.println("An error occurred during file upload: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Method 2: PDF Upload in a Spring Boot Web Application

For web applications, you need an HTTP endpoint to receive the file. Spring Boot makes this process straightforward with its built-in support for multipart file uploads.

Step 1: Set Up a Spring Boot Project

Use Spring Initializr to create a new project with the Spring Web dependency.

Step 2: Create a Controller for File Upload

Create a controller class with a method to handle POST requests. Use the @PostMapping annotation and the MultipartFile parameter to receive the uploaded file.

Key Annotations:

  • @RestController: Marks the class as a controller where every method returns a domain object instead of a view.
  • @PostMapping("/upload"): Maps HTTP POST requests to the uploadPdf method.
  • @RequestParam("file"): Binds the "file" parameter from the multipart/form-data request to the MultipartFile object.

Complete Controller Code:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

@RestController
public class FileUploadController {

    // Define the directory where PDFs will be stored
    private final Path rootLocation = Paths.get("uploads");

    @PostMapping("/upload")
    public ResponseEntity<String> uploadPdf(@RequestParam("file") MultipartFile file) {
        // 1. Validate file input
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("Please select a file to upload.");
        }

        // 2. (Optional) Check if the file is a PDF
        String contentType = file.getContentType();
        if (!"application/pdf".equals(contentType)) {
            return ResponseEntity.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
                                 .body("Only PDF files are allowed.");
        }

        try {
            // 3. Create the upload directory if it doesn't exist
            Files.createDirectories(rootLocation);

            // 4. Resolve the file path
            Path destinationFile = rootLocation.resolve(
                    Paths.get(file.getOriginalFilename()))
                    .normalize().toAbsolutePath();

            // 5. Security check: Ensure the path is within the intended directory
            if (!destinationFile.getParent().equals(this.rootLocation.toAbsolutePath())) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN)
                                     .body("Cannot upload file outside the upload directory.");
            }

            // 6. Save the file to the filesystem
            Files.copy(file.getInputStream(), destinationFile, StandardCopyOption.REPLACE_EXISTING);

            // 7. Return a success response
            return ResponseEntity.ok("PDF uploaded successfully: " + file.getOriginalFilename());

        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                 .body("Failed to upload PDF: " + e.getMessage());
        }
    }
}

Step 3: Configure File Upload Limits (Optional)

By default, Spring Boot limits file uploads. To handle larger PDFs, you can adjust these limits in your application.properties file.

Add to src/main/resources/application.properties:

# Increase the maximum file size (default is 1MB)
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

# Custom upload path (optional)
app.upload.dir=./uploads

You can then inject this property into your controller using @Value("${app.upload.dir}").

Step 4: Test the Upload Endpoint

You can test your endpoint using tools like Postman or curl.

Example using curl:

curl --location 'http://localhost:8080/upload' \
--form 'file=@"/path/to/your/document.pdf"'

Best Practices and Considerations

  1. Security:

    • Validate File Type: Don't rely solely on the client-provided MIME type. Check the file's magic number or use a library like Apache Tika to verify it's a genuine PDF.
    • Sanitize Filenames: Rename the saved file to a random, generated name (e.g., a UUID) to prevent path traversal attacks and conflicts.
    • Set Permissions: Ensure the upload directory has restricted write permissions.
  2. Error Handling: Provide clear and user-friendly error messages without exposing sensitive server information.

  3. Scalability: For high-traffic applications, consider storing files in a cloud storage service (like AWS S3, Google Cloud Storage, or Azure Blob Storage) instead of the local filesystem.

Conclusion

Uploading a PDF in Java can be as simple as copying bytes from one location to another or as complex as handling multipart requests in a web service. The java.nio.file package provides a solid foundation for basic file operations, while the Spring Boot framework dramatically simplifies the creation of robust and secure file upload endpoints for web applications. By following the code examples and best practices outlined above, you can implement a reliable PDF upload feature in your Java projects.