Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

JavaintermediatebackendAI generated

Image Upload Service

Build an image upload service in Java: clients upload images through an HTTP API, the service checks that each file really is an image of an allowed type and size (by its content, not its name), creates thumbnails, stores information about each image in PostgreSQL, and lets only the owner download the original and thumbnails through links that expire. Responses and metadata are JSON handled by Jackson, uploads are streamed so large files don't fill memory, and nothing half-finished is left behind when something fails. You'll learn handling uploads safely in Java, image processing with ImageIO (or Thumbnailator), storing metadata with JDBC, signed expiring download links, and testing an HTTP service.

Estimate
~12h
Steps
6
Completed by
0
Proposed by
codeseed.app

Spring Boot · PostgreSQL · Jackson · Thumbnailator

Project roadmap

  1. 01

    Define the service

    ~1.5h

    Write API.md: POST /images (multipart upload, with the owner from an API key header), GET /images/{id} (metadata as JSON), GET /images/{id}/download?size=original|small|medium (requires a signed link), POST /images/{id}/links (creates a signed link that expires), and DELETE /images/{id}. Define the limits (maximum size and dimensions, allowed types JPEG, PNG and WebP if supported), thumbnail sizes and error format. Create a project with Spring Boot (or Javalin) and Jackson. Done when: API.md defines every endpoint, limit and error.

  2. 02

    Accept and validate uploads

    ~2h

    Stream uploads to a temporary file while enforcing the size limit. Detect the real type from the file's first bytes (magic numbers, or Apache Tika), and read the dimensions with ImageIO's ImageReader without decoding the whole image, refusing images larger than the pixel limit. Reject everything else with a clear error. Done when: a renamed text file, an oversized file and a huge-dimension image are all rejected.

  3. 03

    Generate thumbnails

    ~2h

    Create small and medium thumbnails with Thumbnailator (or ImageIO and Graphics2D with good quality settings), keeping proportions, never enlarging, and applying the EXIF orientation. Write each file to a temporary name and move it into its final place only after everything succeeded; otherwise delete what was created. Done when: uploads produce correct thumbnails, and a failure leaves no files behind.

  4. 04

    Store metadata in PostgreSQL

    ~2h

    Create tables for images (id, owner, original name, type, width, height, size, SHA-256 checksum and created at) and their files, with a migration (Flyway). Save everything in one transaction after the files are ready, using JDBC or Spring Data. Return metadata as JSON with Jackson, and detect duplicates for the same owner by checksum. Done when: metadata is saved and returned, and duplicates are detected.

  5. 05

    Serve downloads securely

    ~2h

    Create signed links: a URL with the image id, size, expiry time and an HMAC-SHA256 signature of those values made with a server secret. The download endpoint checks the signature (with a constant-time comparison) and expiry, then streams the file with the right Content-Type and Content-Disposition headers. Only the owner can create links or delete images. Done when: valid links download files, and tampered or expired links get 403.

  6. 06

    Test it

    ~2.5h

    Write tests with a real PostgreSQL (Testcontainers) and small generated images: each validation rule, thumbnail sizes and orientation, cleanup after a simulated failure, duplicates, signed links (valid, tampered, expired and wrong owner), and deletes removing files and rows. Done when: all tests pass.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~12h · 6 steps

Tech stack

Spring BootPostgreSQLJacksonThumbnailator