๐ Introduction
In this project, we’ll build a simple To-Do List Web Application using Java Spring Boot for the backend, MySQL (via WampServer64) for data storage, and React.js for the frontend. This app lets users perform basic CRUD operations—create, read, update, and delete tasks. It’s perfect for beginners who want to understand how to connect a Java backend with a modern JavaScript frontend. Uniquely, we'll use Notepad as our code editor, proving that you don’t need heavy IDEs to create a fully functional full-stack application from scratch.
๐งฑ Part 1: Set Up the Backend (Java Spring Boot)
๐น Step 1: Generate Spring Boot Project
-
Go to https://start.spring.io
-
Fill in the following:
-
Project: Maven
-
Language: Java
-
Spring Boot: (Use the latest stable version)
-
Group:
com.example
-
Artifact:
todo
-
Name:
todo
-
Description:
Simple ToDo List
-
Package name:
com.example.todo
-
Packaging: Jar
-
Java version: (Pick what you have installed)
-
-
Dependencies:
-
Spring Web
-
Spring Data JPA
-
MySQL Driver
-
Spring Boot DevTools (optional for auto-reload)
-
-
Click Generate, and it will download a
.zip
file. -
Extract the zip to your preferred folder (e.g.,
C:\todo-backend
).
๐น Step 2: Configure MySQL Database on WampServer64
-
Launch WampServer and open phpMyAdmin (usually at
http://localhost/phpmyadmin
). -
Create a new database:
-
Name:
todo_db
-
-
Create a MySQL user or use
root
(default with no password unless you've changed it).
๐น Step 3: Configure application.properties
Open src/main/resources/application.properties
in Notepad:
1 2 3 4 5 6 7 | spring.datasource.url=jdbc:mysql://localhost:3306/todo_db spring.datasource.username=root spring.datasource.password= spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect server.port=8080 |
๐น Step 4: Create the To-Do Entity
Create a file Todo.java
in src/main/java/com/example/todo/model/
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.example.todo.model; import jakarta.persistence.*; @Entity public class Todo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; private boolean completed; // Getters and setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public boolean isCompleted() { return completed; } public void setCompleted(boolean completed) { this.completed = completed; } } |
๐น Step 5: Create Repository
Create TodoRepository.java
in src/main/java/com/example/todo/repository/
:
1 2 3 4 5 6 7 | package com.example.todo.repository; import com.example.todo.model.Todo; import org.springframework.data.jpa.repository.JpaRepository; public interface TodoRepository extends JpaRepository<Todo, Long> { } |
๐น Step 6: Create REST Controller
Create TodoController.java
in src/main/java/com/example/todo/controller/
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | package com.example.todo.controller; import com.example.todo.model.Todo; import com.example.todo.repository.TodoRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @CrossOrigin(origins = "*") // allow frontend @RequestMapping("/api/todos") public class TodoController { @Autowired private TodoRepository repository; @GetMapping public List<Todo> getAll() { return repository.findAll(); } @PostMapping public Todo create(@RequestBody Todo todo) { return repository.save(todo); } @PutMapping("/{id}") public Todo update(@PathVariable Long id, @RequestBody Todo todo) { Todo existing = repository.findById(id).orElseThrow(); existing.setTitle(todo.getTitle()); existing.setCompleted(todo.isCompleted()); return repository.save(existing); } @DeleteMapping("/{id}") public void delete(@PathVariable Long id) { repository.deleteById(id); } } |
๐น Step 7: Run the Backend
Open CMD, navigate to the project folder:
cd C:\todo-backend
.\mvnw spring-boot:run
Backend should start on http://localhost:8080
๐ Part 2: Set Up the Frontend (React.js)
๐น Step 1: Create React App
-
Open CMD and run:
-
Start the app:
It should open http://localhost:3000
.
๐น Step 2: Create Simple CRUD UI
In src/App.js
, replace with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | import React, { useState, useEffect } from 'react'; const API_URL = "http://localhost:8080/api/todos"; function App() { const [todos, setTodos] = useState([]); const [title, setTitle] = useState(""); useEffect(() => { fetchTodos(); }, []); const fetchTodos = async () => { const res = await fetch(API_URL); const data = await res.json(); setTodos(data); }; const addTodo = async () => { if (!title.trim()) return; await fetch(API_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title, completed: false }), }); setTitle(""); fetchTodos(); }; const toggleTodo = async (todo) => { await fetch(`${API_URL}/${todo.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ...todo, completed: !todo.completed }), }); fetchTodos(); }; const deleteTodo = async (id) => { await fetch(`${API_URL}/${id}`, { method: "DELETE" }); fetchTodos(); }; return ( <div style={{ padding: 20 }}> <h2>To-Do List</h2> <input value={title} onChange={(e) => setTitle(e.target.value)} /> <button onClick={addTodo}>Add</button> <ul> {todos.map(todo => ( <li key={todo.id}> <span onClick={() => toggleTodo(todo)} style={{ textDecoration: todo.completed ? "line-through" : "none", cursor: "pointer", }} > {todo.title} </span> <button onClick={() => deleteTodo(todo.id)}>X</button> </li> ))} </ul> </div> ); } export default App; |
๐น Step 3: Allow CORS (already done)
We’ve already allowed CORS in the controller using:
@CrossOrigin(origins = "*")
๐งช Test Everything
Open
http://localhost:3000
in your browser.
You should now be able to:
- Add a to-do
- Toggle completion
- Delete items
The todo_db current contents:
No comments:
Post a Comment