Product Image Management with AWS S3
This Spring Boot application provides a complete product management system with image upload and download capabilities using Amazon S3 for storage.
Features
- Product Management: Create, read, update, and delete products
- Image Upload: Upload product images to Amazon S3
- Image Download: Download and display product images from S3
- Web Interface: Simple HTML interface for testing functionality
- REST API: Complete REST API for product and image management
Prerequisites
- Java 21+
- Maven 3.6+
- PostgreSQL database
- AWS Account with S3 access
- AWS CLI configured (optional, for local development)
Setup Instructions
1. Quick Local Setup (Recommended)
For local development and testing, we use MinIO (S3-compatible storage) and PostgreSQL via Docker:
# Run the setup script ./setup-local.sh # Or manually start services docker compose -f docker-compose-services.yml up -d
This will start:
- PostgreSQL on port 5333
- MinIO (S3-compatible) on port 9000 (API) and 9001 (Console)
- MinIO bucket initialization (creates
product-imagesbucket)
2. Manual Database Setup
Option A: Use Docker (Recommended)
docker compose -f docker-compose-services.yml up -d
Option B: Local PostgreSQL
- Install PostgreSQL
- Create a database named
jfs - Update
application.propertieswith your database credentials
3. Local Development Configuration
The application is pre-configured for local development with MinIO:
# Database Configuration spring.datasource.url=jdbc:postgresql://localhost:5333/jfs spring.datasource.username=amigoscode spring.datasource.password=password # AWS S3 Configuration (MinIO for local development) aws.region=us-east-1 aws.s3.bucket=product-images aws.s3.endpoint-override=http://localhost:9000 aws.s3.path-style-enabled=true aws.access-key-id=minioadmin aws.secret-access-key=minioadmin123
4. Production AWS S3 Configuration
For production deployment with real AWS S3:
Create S3 Bucket
- Log into AWS Console
- Go to S3 service
- Create a new bucket (e.g.,
your-product-images-bucket) - Note the bucket name for configuration
Configure AWS Credentials
Option A: AWS CLI (Recommended for local development)
Option B: Environment Variables
export AWS_ACCESS_KEY_ID=your_access_key export AWS_SECRET_ACCESS_KEY=your_secret_key export AWS_DEFAULT_REGION=us-east-1
Option C: IAM Roles (for EC2/ECS deployment)
- Attach appropriate IAM role with S3 permissions
Update Application Properties for Production
# AWS S3 Configuration (Production) aws.region=us-east-1 aws.s3.bucket=your-product-images-bucket aws.s3.endpoint-override= aws.s3.path-style-enabled=false aws.access-key-id=${AWS_ACCESS_KEY_ID} aws.secret-access-key=${AWS_SECRET_ACCESS_KEY}
5. Required S3 Permissions
Your AWS credentials need the following S3 permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:HeadObject"
],
"Resource": "arn:aws:s3:::your-product-images-bucket/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::your-product-images-bucket"
}
]
}Running the Application
1. Start Local Services
# Quick setup (recommended) ./setup-local.sh # Or manually docker compose -f docker-compose-services.yml up -d
2. Build the Application
3. Run the Application
Or run the JAR file:
java -jar target/product-service.jar
4. Access the Application
- Web Interface: http://localhost:8080
- API Base URL: http://localhost:8080/api/v1/products
- MinIO Console: http://localhost:9001 (minioadmin/minioadmin123)
API Endpoints
Product Management
GET /api/v1/products- Get all productsGET /api/v1/products/{id}- Get product by IDPOST /api/v1/products- Create new product (JSON)POST /api/v1/products- Create new product with image (multipart/form-data)PUT /api/v1/products/{id}- Update productDELETE /api/v1/products/{id}- Delete product
Image Management
POST /api/v1/products/{id}/image- Upload product imageGET /api/v1/products/{id}/image- Download product image
Usage Examples
Create a Product with Image
Using the Web Interface:
- Open http://localhost:8080
- Fill in the product form
- Select an image file
- Click "Create Product"
Using cURL (Single Request - Recommended):
# Create product with image in single request curl -X POST http://localhost:8080/api/v1/products \ -F "name=Sample Product" \ -F "description=A sample product description" \ -F "price=29.99" \ -F "stockLevel=100" \ -F "image=@/path/to/image.jpg"
Using cURL (Separate Requests):
# Create product first curl -X POST http://localhost:8080/api/v1/products \ -H "Content-Type: application/json" \ -d '{ "name": "Sample Product", "description": "A sample product description", "price": 29.99, "stockLevel": 100 }' # Upload image (replace {product-id} with actual ID) curl -X POST http://localhost:8080/api/v1/products/{product-id}/image \ -F "file=@/path/to/image.jpg"
Download Product Image
curl -O http://localhost:8080/api/v1/products/{product-id}/imageProject Structure
src/
├── main/
│ ├── java/com/amigoscode/
│ │ ├── config/
│ │ │ └── AwsS3Config.java # AWS S3 configuration
│ │ ├── product/
│ │ │ ├── Product.java # Product entity
│ │ │ ├── ProductController.java # REST controller
│ │ │ ├── ProductService.java # Business logic
│ │ │ ├── ProductImageService.java # Image handling service
│ │ │ └── ProductRepository.java # Data access
│ │ └── storage/
│ │ └── S3StorageService.java # S3 operations
│ └── resources/
│ ├── static/
│ │ └── index.html # Web interface
│ └── application.properties # Configuration
Docker Deployment
Build Docker Image
Run with Docker Compose
Testing
Unit Tests
Integration Tests
Troubleshooting
Common Issues
-
MinIO Connection Issues (Local Development)
- Ensure MinIO is running:
docker ps | grep minio - Check MinIO logs:
docker logs jfs-minio-local - Verify MinIO is accessible:
curl http://localhost:9000/minio/health/live - Access MinIO console at http://localhost:9001
- Ensure MinIO is running:
-
AWS Credentials Not Found (Production)
- Ensure AWS credentials are properly configured
- Check environment variables or AWS CLI configuration
-
S3 Bucket Access Denied
- Verify bucket name in configuration
- Check IAM permissions for S3 access
- For MinIO: ensure bucket exists and is public
-
Database Connection Issues
- Ensure PostgreSQL is running:
docker ps | grep postgres - Check database logs:
docker logs jfs-postgres-local - Verify database credentials in application.properties
- Ensure PostgreSQL is running:
-
Image Upload Fails
- Check file size limits
- Verify image file format is supported
- Ensure S3/MinIO bucket exists and is accessible
- Check MinIO bucket policy: should be public for downloads
Logs
Check application logs for detailed error messages:
tail -f logs/application.log
Security Considerations
- Use IAM roles instead of access keys when possible
- Implement proper CORS configuration for production
- Add authentication and authorization as needed
- Consider using S3 pre-signed URLs for direct uploads
- Implement file type validation and size limits
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
This project is licensed under the MIT License.