Skip to content

Repository files navigation

board

A bulletin-board (게시판) web application built with Spring Boot. Users can register, log in, and create, edit, delete, search, and comment on posts. Server-rendered with Thymeleaf and backed by a SQL database accessed directly through JdbcTemplate.

⚠️ This is a learning project, not production software. See Known limitations before deploying or reusing this code.

🤖 Working on this repo with a coding agent? Read CLAUDE.md first — it's the agent harness (architecture, commands, conventions, and footguns to avoid).


Tech stack

Layer Technology
Language Java 17
Framework Spring Boot 2.7.12 (spring-boot-starter-web, -thymeleaf, -jdbc)
Views Thymeleaf templates + vanilla JS (fetch) for actions
Data access Spring JdbcTemplate (raw SQL, no JPA/ORM)
Database PostgreSQL (default) — MySQL & H2 drivers also bundled
Build Gradle (wrapper included)
Boilerplate Lombok (@Data)
Deploy Dockerfile (Temurin 17 JRE)

Features

  • Authentication — register an account, log in/out. Login sets a login_id cookie (30-minute expiry) that gates the board pages.
  • Posts — create, view, edit, and delete posts. Edited posts are flagged.
  • Comments — add and delete comments on a post.
  • Search — case-insensitive search across post titles and content.
  • Pagination — 10 posts per page.

Project structure

board/
├── src/main/java/com/choe/board/
│   ├── BoardApplication.java          # Spring Boot entry point
│   ├── HomeController.java            # landing pages ("/", "/other")
│   ├── LoginRegisterController.java   # serves /login and /register pages
│   ├── BulletinBoardController.java   # serves board pages (list/view/create/edit)
│   ├── RestfulController.java         # JSON/REST endpoints for all data actions
│   ├── User.java  Post.java  Comment.java   # data models (Lombok @Data)
│   └── Hwang.java                     # leftover sandbox model (see /test* endpoints)
├── src/main/resources/
│   ├── templates/                     # Thymeleaf HTML (home, login, bulletin, viewpost, ...)
│   ├── static/{css,js,img}/           # per-page stylesheets and fetch-based scripts
│   ├── application.properties         # default (PostgreSQL) datasource config
│   └── application-prod.properties    # "prod" profile (MySQL) datasource config
├── Dockerfile
└── build.gradle

Routes

Pages (server-rendered, @Controller)

Method Path Description Auth
GET / Home / landing page
GET /login Login page
GET /register Registration page
GET /board Post list (?page=, ?query=)
GET /post New-post form
GET /edit Edit-post form (?postId=)
GET /view-post/{id} Single post + its comments

Data actions (@RestController)

Method Path Description
POST /regiSubmit Create a new user
POST /checkDuplicate Check if a username is taken
POST /checkLogin Validate username + password
POST /submit Create a post
POST /submitEdit Edit a post
POST /delete-post Delete a post (author only)
POST /is-editable Check whether current user owns post
POST /submitComment Add a comment
POST /delete-comment Delete a comment (author only)
GET /test/test4 Sandbox/debug endpoints (not part of the app)

Database schema

The app expects these tables to already exist (it does not auto-create them):

-- posts
id SERIAL PRIMARY KEY, title TEXT, author TEXT, content TEXT,
post_date DATE, is_edited BOOLEAN DEFAULT FALSE

-- comments
id SERIAL PRIMARY KEY, post_id INTEGER, author TEXT, content TEXT,
comment_date DATE DEFAULT CURRENT_DATE, is_edited BOOLEAN DEFAULT FALSE

-- "user"   (quoted because user is a reserved word)
id SERIAL PRIMARY KEY, username TEXT, password TEXT, email TEXT,
phone TEXT, created_at TIMESTAMP

-- hwang    (leftover practice table used by /test3 and /test4)
id SERIAL PRIMARY KEY, name TEXT, reserve_date TEXT, room_num INTEGER

Getting started

Prerequisites

  • JDK 17
  • A reachable SQL database (PostgreSQL, MySQL, or use bundled H2)

Configure the database

Edit src/main/resources/application.properties with your own datasource:

spring.datasource.url=jdbc:postgresql://<host>:5432/<db>
spring.datasource.username=<user>
spring.datasource.password=<password>
spring.datasource.driver-class-name=org.postgresql.Driver

Do not commit real credentials — see Known limitations. Prefer environment variables: spring.datasource.password=${DB_PASSWORD}.

Run

./gradlew bootRun          # start on http://localhost:8080

To use the MySQL prod profile instead:

./gradlew bootRun --args='--spring.profiles.active=prod'

Build a jar

./gradlew build
java -jar build/libs/board-0.0.1-SNAPSHOT.jar

Docker

./gradlew build
docker build -t board .
docker run -p 8080:8080 board

Known limitations

This project was built to learn Spring Boot and is intentionally simple. Before reusing it anywhere real, these would need to be addressed:

  • SQL injection — queries are built by string concatenation. Switch to parameterized queries (jdbcTemplate.query(sql, args...) with ? placeholders).
  • Plaintext passwords — passwords are stored and compared as-is. Hash them (e.g. BCrypt via Spring Security).
  • Forgeable auth — login state is an unsigned login_id cookie holding the raw username; anyone can set it. Use real sessions or signed tokens (Spring Security).
  • Secrets in source — datasource credentials should come from environment variables, not be committed to application.properties.
  • build/ is committed — the compiled build/ directory is checked in; it should be git-ignored.
  • Debug endpoints/test/test4 and the hwang table are leftovers and should be removed.

License

No license specified. Personal learning project by @Froggo23.

About

Bulletin-board web app — Spring Boot, Thymeleaf, JdbcTemplate. A learning project with honest known-limitations notes

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages