This example demonstrates how to integrate malware and virus scanning into a Spring Boot file upload application using the attachmentAV API.
File uploads are a common vector for malware distribution. When users upload files to your application, you need to scan them for viruses and malware before processing or storing them. This prevents infected files from compromising your system or being distributed to other users.
attachmentAV provides a REST API that scans files for malware and viruses in real-time. This example shows how to integrate the attachmentAV API into a Spring Boot application to scan uploaded files before accepting them.
┌─────────────────────┐
│ │
│ Web Browser │
│ │
└──────────┬──────────┘
│
│ HTTP POST
│
▼
┌─────────────────────┐
│ │
│ Spring Boot │
│ Application │
│ │
└──────────┬──────────┘
│
│ HTTPS POST
│
▼
┌─────────────────────┐
│ │
│ attachmentAV API │
│ │
└─────────────────────┘
This application provides two file upload capabilities:
- Users upload one file at a time through a simple form
- File is immediately sent to the attachmentAV API for scanning
- Results (clean, infected, or failed) are displayed to the user
- Infected files are rejected with the virus/malware name shown
- Users can select and upload multiple files simultaneously
- Files are scanned concurrently with a maximum of 3 concurrent API calls to the attachmentAV API
- This is achieved using a fixed thread pool (
ExecutorServicewith 3 threads) - Results are aggregated and displayed showing counts of:
- Clean files
- Infected files (with virus names)
- Failed scans
- Concurrent scanning: Multiple files are scanned in parallel (max 3 at a time) for better performance
- Configurable file size limits: Max file size and request size can be adjusted in
application.properties - Error handling: Proper error messages for infected files, scan failures, and API errors
- Clean UI: Simple white-background interface with two forms side by side
- Java 17 or later
- Maven 3.6+
- attachmentAV API key (get one at attachmentav.com)
- Set your attachmentAV API key as an environment variable:
export ATTACHMENTAV_API_KEY=your-api-key-here- Adjust file upload limits (optional):
Edit src/main/resources/application.properties:
# Maximum size for a single file
spring.servlet.multipart.max-file-size=10MB
# Maximum size for the entire request (important for multi-file uploads)
spring.servlet.multipart.max-request-size=50MB- Clone the repository:
git clone https://github.com/widdix/attachmentav-example-java-spring-boot.git
cd attachmentav-spring-boot-file-upload-example- Run with Maven:
./mvnw spring-boot:runOr on Windows:
mvnw.cmd spring-boot:run- Build and run the JAR:
./mvnw clean package
java -jar target/uploading-files-complete-0.0.1-SNAPSHOT.jar- Access the application:
Open your browser and navigate to:
http://localhost:8080
You'll see two upload forms:
- Left: Single file upload
- Right: Multiple files upload
Upload test files to verify the integration:
-
Clean file: Upload a regular text or image file
- Expected: "File has been scanned and is clean!"
-
EICAR test file: Download the EICAR test file to test virus detection
- Expected: "File is infected: EICAR-Test-File"
-
Multiple files: Select multiple files and upload them together
- Expected: Summary showing counts of clean, infected, and failed scans
src/
├── main/
│ ├── java/com/example/uploadingfiles/
│ │ ├── FileUploadController.java # Main controller with upload endpoints
│ │ ├── UploadingFilesApplication.java # Spring Boot application entry point
│ │ └── attachmentav/
│ │ ├── AttachmentAVService.java # Service for attachmentAV API calls
│ │ └── AttachmentAVException.java # Custom exception
│ └── resources/
│ ├── application.properties # Configuration
│ └── templates/
│ └── uploadForm.html # Upload form UI
- User selects a file and clicks "Scan File"
- File is sent to
/endpoint as multipart/form-data FileUploadController.handleFileUpload()receives the fileAttachmentAVService.scanFile()sends the file to attachmentAV API- API returns scan result (clean, infected, or no)
- User sees result message
- User selects multiple files and clicks "Scan Files"
- Files are sent to
/upload-multipleendpoint FileUploadController.handleMultipleFileUpload()receives files- Each file is submitted to a thread pool (max 3 concurrent scans)
CompletableFuturemanages async scanning- Results are collected and aggregated
- User sees summary with counts of clean/infected/failed files
// Fixed thread pool ensures max 3 concurrent API calls -> can be adjusted depending on attachmentAV subscription
private static final int MAX_CONCURRENT_REQUESTS = 3;
private final ExecutorService executorService = Executors.newFixedThreadPool(MAX_CONCURRENT_REQUESTS);
// Each file is scanned asynchronously
CompletableFuture<FileResult> future = CompletableFuture.supplyAsync(() -> {
ScanResult scanResult = attachmentAVService.scanFile(file);
return new FileResult(file.getOriginalFilename(), scanResult, null);
}, executorService);- URL:
https://eu.developer.attachmentav.com/v1/scan/sync/binary - Method: POST
- Headers:
x-api-key: Your API keyContent-Type: application/octet-streamContent-Length: File size in bytes
- Body: Binary file content
- Response: JSON with scan results
Example response:
{
"status": "clean",
"finding": null
}Or for infected files:
{
"status": "infected",
"finding": "EICAR-Test-File"
}This project is open source and available under the terms specified in the repository.
- attachmentAV Documentation
- Spring Boot Documentation
- EICAR Test File - Safe file to test antivirus detection

