A modern, real-time chat application built with Spring Boot, WebSockets, and Thymeleaf. This application enables users to communicate in real-time with a responsive web interface and persistent message storage.
- Overview
- Features
- Architecture
- Project Structure
- Prerequisites
- Installation & Setup
- Configuration
- Usage
- API Endpoints
- WebSocket Events
- Technologies Used
- Database Schema
- Contributing
- License
- Troubleshooting
This Chat Application is a full-stack solution for real-time messaging. It combines the robustness of Spring Boot backend with the interactivity of WebSocket communication and a dynamic Thymeleaf templated frontend. Users can:
- Create accounts and login securely
- Join chat rooms or start direct conversations
- Receive real-time message notifications
- View chat history
- See online/offline status of users
The application is designed with scalability, security, and user experience in mind.
- β Real-Time Messaging: Instant message delivery via WebSockets
- β User Authentication: Secure login and registration system
- β Multiple Chat Rooms: Create and join different conversation groups
- β Direct Messaging: One-on-one private conversations
- β Online Status: See who's currently active
- β Message History: Persistent message storage in database
- β User Profiles: Customizable user information
- β Responsive Design: Works on desktop and mobile devices
- β Message Notifications: Real-time notifications for new messages
- β Typing Indicators: See when others are typing
- β User Search: Find and connect with other users
- β Session Management: Automatic session handling
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client (Browser) β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Thymeleaf Template Views (HTML/CSS/JS) ββ
β β - Chat Interface ββ
β β - User Authentication ββ
β β - Room Management ββ
β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β β HTTP/WebSocket β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ
β
βββββββββββΌβββββββββββββ
β Network Layer β
β (HTTP, WebSocket) β
βββββββββββ¬βββββββββββββ
β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β Spring Boot Backend Application β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Web Layer (Controllers) β β
β β - AuthController β β
β β - ChatController β β
β β - UserController β β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ β
β β WebSocket Handler Layer β β
β β - WebSocketHandler β β
β β - Message Listener β β
β β - Connection Manager β β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ β
β β Business Logic (Services) β β
β β - ChatService β β
β β - UserService β β
β β - MessageService β β
β β - RoomService β β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ β
β β Data Access Layer (Repositories) β β
β β - UserRepository β β
β β - MessageRepository β β
β β - ChatRoomRepository β β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β β
βββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββΌβββββββββββββ
β Database (MySQL) β
β - Users Table β
β - Messages Table β
β - Chat Rooms Table β
β - Sessions Table β
ββββββββββββββββββββββββ
Chat_App/
βββ src/
β βββ main/
β β βββ java/
β β β βββ com/
β β β βββ chatapp/
β β β βββ controller/ # Request handlers
β β β β βββ AuthController.java
β β β β βββ ChatController.java
β β β β βββ UserController.java
β β β β
β β β βββ service/ # Business logic
β β β β βββ ChatService.java
β β β β βββ UserService.java
β β β β βββ MessageService.java
β β β β βββ RoomService.java
β β β β
β β β βββ model/ # Entity classes
β β β β βββ User.java
β β β β βββ Message.java
β β β β βββ ChatRoom.java
β β β β βββ UserSession.java
β β β β
β β β βββ repository/ # Data access
β β β β βββ UserRepository.java
β β β β βββ MessageRepository.java
β β β β βββ ChatRoomRepository.java
β β β β
β β β βββ websocket/ # WebSocket handling
β β β β βββ WebSocketHandler.java
β β β β βββ WebSocketConfig.java
β β β β βββ MessageListener.java
β β β β
β β β βββ config/ # Configuration classes
β β β β βββ SecurityConfig.java
β β β β βββ WebConfig.java
β β β β βββ DatabaseConfig.java
β β β β
β β β βββ util/ # Utility classes
β β β β βββ JwtUtil.java
β β β β βββ ValidationUtil.java
β β β β
β β β βββ ChatApplication.java # Main application
β β β
β β βββ resources/
β β β βββ application.properties # Application configuration
β β β βββ application-dev.properties
β β β βββ templates/ # Thymeleaf templates
β β β β βββ index.html
β β β β βββ login.html
β β β β βββ register.html
β β β β βββ chat.html
β β β β βββ rooms.html
β β β β βββ profile.html
β β β βββ static/ # Static files
β β β βββ css/
β β β β βββ style.css
β β β βββ js/
β β β βββ chat.js
β β β βββ websocket.js
β β β βββ app.js
β β β
β β βββ test/ # Test classes
β β βββ java/
β β βββ com/chatapp/
β β βββ ChatServiceTest.java
β β βββ UserServiceTest.java
β β βββ WebSocketTest.java
β β
β βββ pom.xml # Maven dependencies
β
βββ .gitignore
βββ .gitattributes
βββ mvnw & mvnw.cmd # Maven wrapper scripts
βββ README.md # This file
Before you begin, ensure you have the following installed:
- Java 8+ (Java 11 or 17 recommended)
- Maven 3.6+ or Gradle 6.0+
- MySQL 5.7+ or PostgreSQL 10+
- Git
- Node.js (optional, for frontend development)
- Docker (for containerized deployment)
- Redis (for session caching)
- Nginx (for reverse proxy)
git clone https://github.com/anushkax2311/Chat_App.git
cd Chat_App# Create database
mysql -u root -p -e "CREATE DATABASE chat_app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
# Create user (optional)
mysql -u root -p -e "CREATE USER 'chat_user'@'localhost' IDENTIFIED BY 'password123';"
mysql -u root -p -e "GRANT ALL PRIVILEGES ON chat_app_db.* TO 'chat_user'@'localhost';"
mysql -u root -p -e "FLUSH PRIVILEGES;"# Create database
createdb chat_app_db
# Create user (optional)
createuser chat_user
psql -U postgres -d chat_app_db -c "ALTER USER chat_user WITH PASSWORD 'password123';"Create a docker-compose.yml:
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: chat_app_db
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: chat_app_db
MYSQL_USER: chat_user
MYSQL_PASSWORD: password123
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:Start the database:
docker-compose up -dEdit src/main/resources/application.properties:
# Server Configuration
server.port=8080
server.servlet.context-path=/
# Spring Application
spring.application.name=chat-app
# Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/chat_app_db
spring.datasource.username=chat_user
spring.datasource.password=password123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA/Hibernate Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.properties.hibernate.format_sql=true
# WebSocket Configuration
spring.websocket.enabled=true
spring.websocket.path=/ws
# Thymeleaf Configuration
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false
# Logging Configuration
logging.level.root=INFO
logging.level.com.chatapp=DEBUG
# Session Configuration
server.servlet.session.timeout=1h
spring.session.store-type=jdbc
# File Upload Configuration
spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=10MB
# Security
app.jwt.secret=your-secret-key-here-change-in-production
app.jwt.expiration=86400000# Using Maven wrapper (no Maven installation needed)
./mvnw clean install
# Or using installed Maven
mvn clean install# Using Maven wrapper
./mvnw spring-boot:run
# Or using installed Maven
mvn spring-boot:run
# Or running the JAR file
java -jar target/chat-app.jarThe application should now be running at http://localhost:8080
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
logging.level.com.chatapp=DEBUG
spring.devtools.restart.enabled=truespring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
logging.level.com.chatapp=WARN
server.compression.enabled=true
spring.thymeleaf.cache=trueThe application uses STOMP protocol over WebSocket for real-time messaging.
// JavaScript WebSocket Example
const socket = new SockJS('/ws');
const stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame.headers['server']);
// Subscribe to room messages
stompClient.subscribe('/topic/room/123', function(message) {
console.log('New message: ' + message.body);
});
});curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "john_doe",
"email": "john@example.com",
"password": "secure_password123"
}'curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "secure_password123"
}'curl -X POST http://localhost:8080/api/rooms \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {token}" \
-d '{
"name": "General Discussion",
"description": "General chat for all users",
"isPrivate": false
}'stompClient.send("/app/chat", {}, JSON.stringify({
sender: "john_doe",
content: "Hello everyone!",
roomId: 123,
timestamp: new Date()
}));Simply navigate to http://localhost:8080 in your browser after logging in.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Register a new user |
| POST | /api/auth/login |
User login |
| POST | /api/auth/logout |
User logout |
| POST | /api/auth/refresh |
Refresh authentication token |
| GET | /api/auth/verify |
Verify token validity |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users/{id} |
Get user profile |
| PUT | /api/users/{id} |
Update user profile |
| DELETE | /api/users/{id} |
Delete user account |
| GET | /api/users/search |
Search users |
| GET | /api/users/online |
Get online users |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/rooms |
Get all chat rooms |
| POST | /api/rooms |
Create new chat room |
| GET | /api/rooms/{id} |
Get room details |
| PUT | /api/rooms/{id} |
Update room |
| DELETE | /api/rooms/{id} |
Delete room |
| POST | /api/rooms/{id}/join |
Join a room |
| POST | /api/rooms/{id}/leave |
Leave a room |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/messages/{roomId} |
Get room messages |
| GET | /api/messages/dm/{userId} |
Get direct messages |
| POST | /api/messages |
Send message (REST) |
| DELETE | /api/messages/{id} |
Delete message |
# Send message to room
/app/chat/send
# Subscribe to room messages
/topic/room/{roomId}
# Subscribe to direct messages
/topic/dm/{userId}
# Subscribe to user status
/topic/status/{userId}
# Subscribe to typing indicators
/topic/typing/{roomId}
{
"id": "msg-123",
"sender": "john_doe",
"senderId": 1,
"content": "Hello world!",
"roomId": 5,
"messageType": "TEXT",
"timestamp": "2024-03-27T10:30:00Z",
"isEdited": false,
"reactions": ["π", "β€οΈ"]
}- Spring Boot 2.x/3.x - Application framework
- Spring Security - Authentication & authorization
- Spring Data JPA - Data access
- Spring WebSocket - Real-time communication
- Spring Thymeleaf - Server-side templating
- Thymeleaf - Template engine
- HTML5 - Markup language
- CSS3 - Styling
- JavaScript (Vanilla/jQuery) - Client-side scripting
- SockJS - WebSocket emulation
- STOMP - Messaging protocol
- MySQL 8.0 / PostgreSQL
- JPA/Hibernate - ORM
- Maven - Build automation
- Git - Version control
- JUnit - Unit testing
- Mockito - Mocking framework
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
full_name VARCHAR(100),
avatar_url VARCHAR(255),
status ENUM('ONLINE', 'OFFLINE', 'AWAY') DEFAULT 'OFFLINE',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);CREATE TABLE messages (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
sender_id BIGINT NOT NULL,
room_id BIGINT,
receiver_id BIGINT,
content LONGTEXT NOT NULL,
message_type ENUM('TEXT', 'IMAGE', 'FILE') DEFAULT 'TEXT',
is_edited BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sender_id) REFERENCES users(id),
FOREIGN KEY (room_id) REFERENCES chat_rooms(id),
FOREIGN KEY (receiver_id) REFERENCES users(id)
);CREATE TABLE chat_rooms (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
description TEXT,
created_by BIGINT NOT NULL,
is_private BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (created_by) REFERENCES users(id)
);CREATE TABLE room_members (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
room_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_member (room_id, user_id),
FOREIGN KEY (room_id) REFERENCES chat_rooms(id),
FOREIGN KEY (user_id) REFERENCES users(id)
);Contributions are welcome! To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Java naming conventions
- Write unit tests for new features
- Keep commits atomic and well-described
- Update documentation when needed
- Run tests before submitting PR:
mvn test
This project is open source and available under the MIT License.
Cause: Database connection failed Solution:
# Check if MySQL is running
mysql -u root -p -e "SELECT 1;"
# Verify database exists
mysql -u root -p -e "SHOW DATABASES;"
# Check application.properties credentials
cat src/main/resources/application.properties | grep datasourceCause: WebSocket endpoint not configured properly Solution:
# Ensure WebSocket is enabled in application.properties
spring.websocket.enabled=true
spring.websocket.path=/wsSolution: Change port in application.properties
server.port=8081Cause: Thymeleaf templates in wrong location
Solution: Ensure templates are in src/main/resources/templates/
Solution: Login again or refresh token
curl -X POST http://localhost:8080/api/auth/refresh \
-H "Authorization: Bearer {expired_token}"- Always use HTTPS in production
- Change JWT secret in production
- Implement rate limiting for API endpoints
- Use prepared statements for SQL queries (JPA does this automatically)
- Validate all user inputs
- Keep dependencies updated:
mvn dependency:check
- Spring Boot Documentation
- Spring WebSocket Guide
- Thymeleaf Documentation
- MySQL Documentation
- STOMP Protocol
For questions or issues:
- Open an issue on GitHub Issues
- Check existing issues and discussions
- Review the documentation
Thanks to all contributors and the open-source community for making this project possible.
Made with β€οΈ by anushkax2311
β If this project helped you, please consider giving it a star!