A production-ready web application built with Spring Boot 3.5.8 featuring secure user authentication, multi-user session management, and a full-featured board system with pagination and search capabilities.
Developed as part of Java Spring course at Sungkyul University demonstrating enterprise-level web development patterns.
This is a full-stack Spring Boot application that implements:
- Secure user authentication with BCrypt password encryption
- Multi-user session management using UUID-based session tracking
- Board/Blog system with CRUD operations, pagination, and search
- File upload capabilities with configurable size limits
- Input validation using Jakarta Bean Validation
- Production-ready features including session management and security best practices
Developer: Wai Yan Naung
Framework: Spring Boot 3.5.8
Java Version: 21
Database: MySQL 8.x
- Secure user registration with encrypted password storage (BCrypt)
- Session-based authentication with UUID tracking for concurrent multi-user support
- Login/logout functionality with proper session management
- Protected routes requiring authentication before access
- Create, view, and list board posts with rich metadata
- Server-side validation for content integrity (title max 200 chars, content max 5000 chars)
- Search functionality with case-insensitive keyword filtering
- Pagination support (3 posts per page, configurable)
- Automatic date formatting (dd-MM-yyyy)
- Author name automatically assigned from logged-in user session
- Independent session management per user using UUID
- Concurrent user support without session conflicts
- Each user maintains their own authenticated session
- Secure session cookie handling with configurable timeout
- Configurable file size limits (max 10MB per file, 30MB per request)
- Static file serving for uploaded content
- Secure file storage in designated upload directory
- Layered architecture: Controller → Service → Repository
- DTO pattern for clean data transfer
- Builder pattern for entity creation
- Input validation with @Valid annotations
- Exception handling for authentication failures
- Server-side defaults for views/likes counters
| Layer | Technology |
|---|---|
| Backend | Spring Boot 3.5.8, Spring MVC, Spring Data JPA |
| Frontend | Thymeleaf, Bootstrap 4.5.2, HTML5, CSS3, JavaScript |
| Database | MySQL 8.x with JPA/Hibernate ORM |
| Security | Spring Security (BCrypt password hashing), Session Management |
| Build Tool | Maven 3.x |
| Template Engine | Thymeleaf |
| Validation | Jakarta Bean Validation API |
| Monitoring | Spring Boot Actuator |
| JS Libraries | CounterUp, Easing, Isotope, Lightbox, OwlCarousel, Typed.js, Waypoints, WOW.js |
| IDE / Tools | Visual Studio Code, Git, GitHub |
CREATE TABLE member (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL, -- BCrypt encrypted
age VARCHAR(50) NOT NULL,
mobile VARCHAR(50) NOT NULL,
address VARCHAR(255)
);CREATE TABLE board (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
content TEXT(5000) NOT NULL,
user VARCHAR(255) NOT NULL, -- Author name (from session)
newdate VARCHAR(50) NOT NULL, -- Format: dd-MM-yyyy
count VARCHAR(50) NOT NULL DEFAULT '0', -- View count
likec VARCHAR(50) NOT NULL DEFAULT '0', -- Like count
password VARCHAR(255) NOT NULL, -- Post password (for edit/delete)
email VARCHAR(255) NOT NULL, -- Author email
mobile VARCHAR(50) NOT NULL,
name VARCHAR(255) NOT NULL,
address VARCHAR(255),
age VARCHAR(50) NOT NULL DEFAULT '0'
);- Java JDK 21 or higher
- MySQL Server 8.x
- Maven 3.6+ (or use included
mvnw.cmd) - VS Code with Spring Boot Extension Pack (recommended)
vmware.vscode-boot-dev-pack- Spring Boot Dev Packvscjava.vscode-java-pack- Java Extension Packcweijan.vscode-mysql-client2- MySQL Clientcweijan.dbclient-jdbc- Database Client
# Clone the repository
git clone https://github.com/wynaung19/Java_Spring.git
# Navigate to project directory
cd Java_Spring- Create MySQL database:
CREATE DATABASE spring CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;- Update database credentials in
src/main/resources/application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Seoul
spring.datasource.username=root
spring.datasource.password=YOUR_PASSWORD # Change this- Tables will be auto-created on first run (
spring.jpa.hibernate.ddl-auto=update)
# Windows
mvnw.cmd clean install
# Linux/Mac
./mvnw clean installOption 1: Using VS Code Spring Boot Dashboard
- Open project in VS Code
- Open Spring Boot Dashboard (left sidebar)
- Click
▶️ Run button next toSkuApplication
Option 2: Using Maven Command
# Windows
mvnw.cmd spring-boot:run
# Linux/Mac
./mvnw spring-boot:runOption 3: Using Terminal
java -jar target/sku-0.0.1-SNAPSHOT.jarApplication URL: http://localhost:8080
sku/
├── src/main/
│ ├── java/com/waiyannaung/sku/
│ │ ├── SkuApplication.java # 🚀 Application entry point
│ │ ├── controller/
│ │ │ ├── BlogController.java # 📝 Board CRUD & pagination
│ │ │ ├── MemberController.java # 🔐 Authentication & sessions
│ │ │ ├── FileController.java # 📁 File upload handling
│ │ │ ├── BlogRestController.java # 🌐 REST API endpoints
│ │ │ └── SkuController.java # 🧪 Test endpoints
│ │ ├── model/
│ │ │ ├── domain/
│ │ │ │ ├── Board.java # 📋 Board entity (JPA)
│ │ │ │ └── Member.java # 👤 Member entity (JPA)
│ │ │ ├── repository/
│ │ │ │ ├── BoardRepository.java # 🗄️ Board data access
│ │ │ │ └── MemberRepository.java # 🗄️ Member data access
│ │ │ └── service/
│ │ │ ├── BlogService.java # 💼 Board business logic
│ │ │ ├── MemberService.java # 💼 Authentication logic
│ │ │ ├── AddArticleRequest.java # 📦 Board DTO
│ │ │ └── AddMemberRequest.java # 📦 Member DTO
│ │ └── config/ # ⚙️ Configuration classes
│ └── resources/
│ ├── application.properties # ⚙️ Configuration
│ ├── templates/ # 🎨 Thymeleaf views
│ │ ├── board_list.html # List with pagination
│ │ ├── board_view.html # Post detail view
│ │ ├── board_write.html # Create post form
│ │ ├── login.html # Login page
│ │ ├── join_new.html # Registration form
│ │ ├── join_end.html # Success page
│ │ ├── index.html # Homepage
│ │ └── error_page/
│ │ └── article_error.html # Error handling
│ └── static/ # 🎨 Static resources
│ ├── css/ # Bootstrap & styles
│ ├── js/ # JavaScript libraries
│ ├── img/ # Images
│ └── upload/ # User uploads
├── pom.xml # 📦 Maven dependencies
├── mvnw.cmd / mvnw # Maven wrapper
└── README.md # 📖 This file
| Route | Method | Description |
|---|---|---|
/ |
GET | 🏠 Homepage (portfolio) |
/member_login |
GET | 🔐 Login page |
/join_new |
GET | ✍️ Registration page |
/api/members |
POST | 📝 User registration |
/api/login_check |
POST | ✅ Authentication |
| Route | Method | Description |
|---|---|---|
/board_list |
GET | 📋 List posts (paginated, searchable) |
/board_view/{id} |
GET | 👁️ View single post |
/board_write |
GET | ✍️ Create post form |
/api/boards |
POST | 💾 Submit new post |
/api/logout |
GET | 🚪 Logout & clear session |
// One-way hash - cannot be decrypted
String encodedPassword = passwordEncoder.encode(rawPassword);
// Stored in DB: $2a$10$N9qo8uLOickgx2ZMRZoMye...// Each user gets unique UUID session
String sessionId = UUID.randomUUID().toString();
session.setAttribute("userId", sessionId); // Tracking ID
session.setAttribute("userName", member.getName()); // Display name
session.setAttribute("email", member.getEmail()); // Email// Redirect to login if not authenticated
if (session.getAttribute("userId") == null) {
return "redirect:/member_login";
}// Author assigned from session (prevents client manipulation)
String userName = (String) session.getAttribute("userName");
request.setUser(userName); // Not from form input- Go to http://localhost:8080/join_new
- Fill in: Name, Email, Password, Age, Mobile, Address
- Submit → Password encrypted with BCrypt
- Success page displayed
- Go to http://localhost:8080/member_login
- Enter email and password
- Session created (UUID + user info)
- Redirected to board list
- Click "글쓰기" (Write) button
- Login required (auto-redirect if not logged in)
- Fill form:
- Title (max 200 chars) ✅ Required
- Password (for post security)
- Content (max 5000 chars) ✅ Required
- Author auto-set from session
- Date auto-set (dd-MM-yyyy)
- Submit → Validated & saved
- Enter keyword → Searches titles (case-insensitive)
- Clear search → Shows all posts
- 3 posts per page
- Use numbered pagination links
- Previous/Next buttons
- Click "로그아웃" button
- Session cleared
- Redirected to login
spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Seoul
spring.datasource.username=root
spring.datasource.password=123123 # Change this
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=trueserver.servlet.session.timeout=300s # 5 minutes
server.servlet.session.cookie.secure=true # HTTPS onlyspring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=30MB
spring.servlet.multipart.location=./src/main/resources/static/upload- ✅ Register → Password encrypted in DB
- ✅ Login success → Session created
- ✅ Login fail → Error message
- ✅ Duplicate email → Prevented
- ✅ Logout → Session cleared
- ✅ Create post → Author from session
- ✅ Validation → Empty title rejected
- ✅ Date format → dd-MM-yyyy
- ✅ Search → Case-insensitive
- ✅ Pagination → Works correctly
- ✅ Protected route → Redirects to login
- ✅ Multi-user → Independent sessions
- ✅ Session timeout → Works as configured
MySQL connection error:
- ✅ MySQL running:
mysql -u root -p - ✅ Database exists:
CREATE DATABASE spring; - ✅ Credentials correct in
application.properties
Port 8080 in use:
# Windows: Kill process
netstat -ano | findstr :8080
taskkill /PID <pid> /F
# Or change port
server.port=8081Correct credentials but login fails:
- ✅ Check PasswordEncoder bean configured
- ✅ Verify user in DB:
SELECT * FROM member WHERE email='test@test.com'; - ✅ Password should start with
$2a$or$2b$
Session lost immediately:
- ✅ Enable cookies in browser
- ✅ If HTTP (not HTTPS):
server.servlet.session.cookie.secure=false
500 Error creating post:
- ✅ Session has
userName: Check login sets it - ✅ All NOT NULL fields have values
- ✅ Validation passes (title/content not blank)
Author shows UUID:
- ✅ Fixed: Now uses
userNamefrom session - ✅ Check
board_write.html:th:value="${userName}"
This project demonstrates:
- ✅ Spring Boot 3.5.8 - Auto-configuration, starters
- ✅ Spring MVC - Controllers, request mapping
- ✅ Spring Data JPA - Repositories, entities, queries
- ✅ Spring Security - BCrypt, authentication
- ✅ Thymeleaf - Server-side templates
- ✅ MySQL & Hibernate - ORM, database management
- ✅ Session Management - Multi-user support with UUID
- ✅ Input Validation - Bean Validation API
- ✅ Layered Architecture - Controller → Service → Repository
- ✅ DTO Pattern - Clean data transfer
- ✅ Security Best Practices - Password hashing, session security
- Edit/delete posts with password verification
- View counter increment
- Like/unlike functionality
- Comment system
- User profile pages
- Post categories
- Rich text editor (Markdown)
- Email verification
- Password reset
- Unit & integration tests (JUnit 5)
- REST API with JWT
- Role-based access control
- Database migrations (Flyway)
- Redis session store
- Caching layer
- Docker containerization
- CI/CD pipeline