MinIO is a lightweight, high-performance, S3-compatible object storage solution that works great for storing all kinds of files—including images. If you're building a web or mobile application with
Spring Boot, integrating image uploads to MinIO can help you manage files easily and securely.
In this article, you’ll learn how to
upload image files to MinIO using Spring Boot, by building a REST API that accepts image uploads and stores them in a MinIO bucket.
What You’ll Learn
- How to configure MinIO in Spring Boot
- How to create a file upload API endpoint
- How to upload images like PNG, JPEG, etc., to MinIO
- How to organize and access stored image files
Note: This article assumes your Spring Boot app is already connected to MinIO. If not, check out tutorials like Connect Spring Boot to MinIO Server or MinIO Dependency Setup in Spring Boot.
Step 1: Add MinIO Java SDK to Your Project
First, include the MinIO SDK in your
pom.xml
if you're using Maven:
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.3</version> <!-- Check for the latest version -->
</dependency>
Step 2: Configure MinIO in application.properties
Add your MinIO connection details in the
application.properties
file:
minio.url=http://localhost:9000
minio.accessKey=minioadmin
minio.secretKey=minioadmin
minio.bucketName=images
You can use
application.yml
if preferred, as long as your config is correctly injected.
Step 3: Create a MinIO Client Configuration
Create a config class to initialize the MinIO client:
@Configuration
public class MinioConfig {
@Value("${minio.url}")
private String url;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(url)
.credentials(accessKey, secretKey)
.build();
}
}
Step 4: Build a Service to Upload Image Files
Now let’s create a service that handles uploading image files:
@Service
public class ImageUploadService {
@Value("${minio.bucketName}")
private String bucketName;
private final MinioClient minioClient;
public ImageUploadService(MinioClient minioClient) {
this.minioClient = minioClient;
}
public String uploadImage(MultipartFile file) throws Exception {
// Check for image content type
String contentType = file.getContentType();
if (contentType == null || !contentType.startsWith("image/")) {
throw new IllegalArgumentException("Only image files are allowed.");
}
// Ensure the bucket exists
boolean found = minioClient.bucketExists(BucketExistsArgs.builder()
.bucket(bucketName)
.build());
if (!found) {
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
}
// Generate a unique file name
String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
// Upload the image to MinIO
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(contentType)
.build());
return fileName;
}
}
Step 5: Create a REST API to Handle Uploads
Now expose the upload functionality through a controller:
@RestController
@RequestMapping("/api/images")
public class ImageUploadController {
private final ImageUploadService imageUploadService;
public ImageUploadController(ImageUploadService imageUploadService) {
this.imageUploadService = imageUploadService;
}
@PostMapping("/upload")
public ResponseEntity<string> uploadImage(@RequestParam("file") MultipartFile file) {
try {
String fileName = imageUploadService.uploadImage(file);
return ResponseEntity.ok("Image uploaded successfully: " + fileName);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body(e.getMessage());
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Error uploading image: " + e.getMessage());
}
}
}
Step 6: Test the Image Upload API
You can test the API using
Postman,
curl, or your frontend app.
Example using curl
:
curl -X POST http://localhost:8080/api/images/upload \
-F "file=@/path/to/image.jpg"
If successful, the API will return the uploaded file name.
Best Practices
- Always validate file type to prevent unwanted uploads.
- Use unique names to avoid overwriting files.
- Store the returned file name or URL in your database for later use.
- Set up CORS rules on MinIO if accessing images from a frontend.
- For production, store MinIO credentials in environment variables or a secure config server.
image quote pre code