Short Link is a small URL shortener web application that converts long URLs into short, shareable links and redirects visitors to the original URL. It provides a simple web UI, support for guest and authenticated users, and basic analytics (click counts).
- Create short URLs (guest users can create public short URLs; authenticated users can create public or private short URLs and set expiry)
- Redirect short links to the original URL
- Per-URL expiration support
- Basic user management and auth (login, registration) with role-based admin access
- Persistence via JPA (Postgres by default; H2 available at runtime)
- Web UI implemented with Thymeleaf + Bootstrap
- Language(s): Java (primary), HTML (Thymeleaf), CSS
- Framework / runtime: Spring Boot 3.5.x (Maven), Java 21 (pom.xml)
- Notable libraries:
- spring-boot-starter-web
- spring-boot-starter-data-jpa
- spring-boot-starter-security
- spring-boot-starter-thymeleaf (+ thymeleaf-layout-dialect)
- Flyway (database migrations)
- H2 / PostgreSQL drivers
- WebJars Bootstrap (UI)
.pom.xml
mvnw, mvnw.cmd
.mvn/
compose.yaml
src/
main/
java/com/darc/shortlink/
ShortLinkApplication.java # Spring Boot entry point
ApplicationProperties.java # app.* configuration mapping
config/
WebSecurityConfig.java # security rules
controller/
HomeController.java # web endpoints (/, /short-urls, /s/{key}, /login)
SecurityUtils.java # helper to obtain current user
services/ # business logic (create/resolve short links)
repositories/ # persistence layer (JPA repositories)
domain/ # entities, DTOs, forms, exceptions
resources/
application.properties # default app configuration (Postgres by default)
templates/ # Thymeleaf templates (index.html, login, ...)
static/ # static assets (css/js/images)
src/test/ # tests
README.md
- The application starts at
ShortLinkApplication. HomeControllerserves the public index (/) and handles the short URL creation POST at/short-urls.- Short links are accessed with
/s/{shortKey}which redirects to the original URL (and tracks access). - Security is configured in
WebSecurityConfig— public endpoints include/,/short-urls,/s/**,/login,/register;/my-urlsrequires authentication;/admin/**requiresROLE_ADMIN. ApplicationPropertiesmapsapp.base-url,app.default-expiry-in-days, andapp.validate-original-url.
- JDK 21 (or a Java 21+ runtime as declared in pom.xml)
- Maven (recommended: use the included Maven wrapper
./mvnw) - PostgreSQL if using the default datasource, or let the app use H2 for quick testing
- Docker / Docker Compose (optional —
compose.yamlis included)
- Clone:
git clone https://github.com/Darc99/short-link.git
cd short-link- Run with Maven wrapper:
# Run directly
./mvnw spring-boot:run
# OR build jar and run
./mvnw clean package
java -jar target/*.jar- Run with Docker Compose (build + run):
docker compose -f compose.yaml up --build- Run tests:
./mvnw testThe web UI will be available at: http://localhost:8080 (default Spring Boot port)
Default configuration lives in src/main/resources/application.properties. Important properties:
-
Datasource (Postgres by default)
- spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
- spring.datasource.username=postgres
- spring.datasource.password=postgres
-
App properties (mapped by
ApplicationProperties):- app.base-url (default: http://localhost:8080)
- app.default-expiry-in-days (default: 30)
- app.validate-original-url (default: true)
To override configuration, set environment variables or provide an external application.properties/application.yml. Example environment variables:
SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/shortlink
SPRING_DATASOURCE_USERNAME=postgres
SPRING_DATASOURCE_PASSWORD=postgres
APP_BASE_URL=http://example.com
APP_DEFAULT_EXPIRY_IN_DAYS=60
APP_VALIDATE_ORIGINAL_URL=falseIf you prefer to use an in-memory database for development, update spring.datasource.url to an H2 URL or rely on the runtime H2 dependency.
-
GET /
- Home page (index) showing public short links and the form to create a new short URL.
-
POST /short-urls
- Form submit endpoint for creating a new short URL. Form fields expected (from UI):
- originalUrl — the long URL to shorten
- isPrivate — checkbox (true/false) to mark as private
- expirationInDays — integer for custom expiry (optional)
- On success, a flash message contains the new short URL.
- Form submit endpoint for creating a new short URL. Form fields expected (from UI):
-
GET /s/{shortKey}
- Redirects to the original long URL for the given short key. If the short link is private/expired/not found, a 404/handled error is returned.
-
GET /login
- Login page (form-based login).
-
GET /my-urls
- Authenticated endpoint: list the logged-in user’s short URLs.
-
/admin/**
- Admin-only endpoints (require ROLE_ADMIN).
Notes: check src/main/java/com/darc/shortlink/controller/HomeController.java and src/main/java/com/darc/shortlink/config/WebSecurityConfig.java for exact route behavior and security rules.
The app expects a form POST. Example using curl to simulate the form:
curl -X POST http://localhost:8080/short-urls \
-d "originalUrl=https://example.com/some/very/long/path" \
-d "isPrivate=false" \
-d "expirationInDays=30"On success the UI will display the created short URL (e.g. http://localhost:8080/s/abc123).
To follow the redirect:
curl -i http://localhost:8080/s/abc123
# Expect a 302 redirect to the original URL- Security:
WebSecurityConfigdisables CSRF (for now) and configures form login (/login) and logout (/logout). Static resources and the public endpoints are permitted to anonymous users. - Persistence: JPA + Flyway are on the classpath — check migration scripts under
src/main/resources/dbif present. - Templates: UI is implemented with Thymeleaf templates under
src/main/resources/templates/and uses Bootstrap (WebJars).
- Application fails on start: ensure your Java version matches
<java.version>in pom.xml (21). - Database errors: verify
spring.datasource.*values or run with Docker Compose if you want a bundled Postgres for development. - Authentication issues: review
WebSecurityConfigand any default users configured in application properties (the default app does not enable a built-in user by default).
Run unit/integration tests:
./mvnw testContributions are welcome. Suggested workflow:
- Fork the repository
- Create a feature branch
- Add tests for new behavior
- Open a pull request describing your changes
Please include a license file (none is included by default). Consider adding LICENSE (MIT / Apache-2.0 / etc.) depending on your preference.