Spring Boot Demo

An interactive portfolio application demonstrating how I build a modern Spring Boot system from browser page to database. It replaces the original third-party API experiment with a self-contained demo: a Thymeleaf landing page, a live feature tour, secured REST APIs, JPA persistence, cache metrics, validation, error handling, and tested behaviour.

Live pages

URL Purpose
/ Thymeleaf landing page based on my Spring portfolio content, with developer profile and contact details.
/showcase Interactive jQuery AJAX tour. It calls the running controllers, shows JPA query results, creates a database record, reads a post twice, and displays live cache statistics.
/api/posts Public paginated/searchable REST read API; POST, PUT, and DELETE require the EDITOR role.
/api/showcase/cache Read-only Caffeine cache statistics for the feature tour.
/actuator/health Public health check.

Run it

Requires JDK 21+.

cd D:\app\springboot-jsonplaceholder-demo
./mvnw.cmd spring-boot:run

Open http://localhost:8080. The local profile uses an in-memory H2 database and automatically loads three sample posts for the feature tour.

The local editor account is intentionally a non-secret demo account:

username: demo-editor
password: changeit

The showcase form never pre-fills or stores credentials; it sends them only to the same local application for the authenticated request. Override them through APP_EDITOR_USERNAME and APP_EDITOR_PASSWORD.

What the feature tour proves

  1. Thymeleaf & MVCHomeController renders / and /showcase; the index uses a server-side model for contact values.
  2. jQuery AJAX & REST controllers — the browser calls GET /api/posts, POST /api/posts, GET /api/posts/{id}, health, and cache-stat endpoints. Responses and errors are displayed directly in the page.
  3. Spring Data JPAPostRepository provides pagination and case-insensitive title search; PostService owns read/write transaction boundaries.
  4. Caching — individual post reads use bounded Caffeine caching. The “Read twice” button produces real cache activity, then requests the cache-stat endpoint.
  5. Security — public portfolio pages and read APIs are open; data mutations require the EDITOR role with BCrypt-backed, stateless HTTP Basic authentication.
  6. Validation & error handling — request records validate input at the boundary and ApiExceptionHandler returns consistent RFC-style problem documents.
  7. Safe concurrent updates — the JPA @Version field makes an outdated update return a conflict instead of silently overwriting a newer change.
  8. Configuration management — typed cache and security settings live in application configuration. The prod profile uses PostgreSQL and requires database/editor environment variables with no committed production secrets.

Build and test

./mvnw.cmd test
./mvnw.cmd package

The integration test verifies the rendered Thymeleaf pages, unauthenticated versus editor-only API access, validation responses, search, and cache metrics.

Project layout

com.hoelee.demo
├── config      typed cache and security configuration
├── post        REST contract, JPA entity, repository, and service layer
├── support     consistent API error mapping
└── web         Thymeleaf pages, cache metrics, and local demo data

Each Java file has a compact learning note in the author/version comment format used by the larger reference application. The source uses 2024 timestamps in the requested evening window; the Git commits themselves retain their real creation times.

Production profile

SPRING_PROFILES_ACTIVE=prod selects PostgreSQL and requires:

APP_DB_URL
APP_DB_USERNAME
APP_DB_PASSWORD
APP_EDITOR_USERNAME
APP_EDITOR_PASSWORD

For production, use a managed secret store and add Flyway or Liquibase migrations before setting ddl-auto to validate.

Description
Portfolio showcase: modern Spring Boot app with Thymeleaf UI, Spring Data JPA, Caffeine caching, Spring Security, validation, and tests.
Readme Unlicense 137 KiB
v1.0.0 Latest
2026-08-19 14:02:57 +00:00
Languages
Java 67.2%
HTML 25.4%
JavaScript 7.4%