Building a Java Full Stack Web Application: A Step-by-Step Guide with Spring Boot and React

 Ever wanted to build a full-stack application using Java on the backend and a popular JavaScript framework on the front end? Java and Spring Boot paired with React make for a powerful combo that’s ideal for creating interactive, responsive web applications. Whether you’re developing a personal project or diving into full-stack development for your career, this guide will walk you through building a basic Java full-stack app using Spring Boot and React.

We’ll keep things practical and hands-on, covering the essential steps to get your application up and running. Let’s dive in!

Step 1: Setting Up the Spring Boot Backend

First, let’s tackle the backend. Spring Boot is a popular choice for Java developers because it simplifies many aspects of building REST APIs. You’ll use Spring Boot to create an API that your React frontend can interact with.

1.1. Initialize Your Spring Boot Project

Head to the Spring Initializr to set up your project. Select the following:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: Latest stable version
  • Dependencies: Add Spring Web (for building REST APIs) and Spring Data JPA (for database interactions)

Download the generated project, unzip it, and open it in your favorite IDE (like IntelliJ or Eclipse).

1.2. Define Your Model Class

Let’s say we’re building a basic task management app. Start by defining a Task model that represents the tasks in your database. Go to the src/main/java folder, create a model package, and add the Task class:

java
package com.example.demo.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Task { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private boolean completed; // Getters and setters }

1.3. Set Up the Repository

Spring Data JPA allows us to interact with the database without writing SQL. Create a TaskRepository interface in a repository package:

java
package com.example.demo.repository; import com.example.demo.model.Task; import org.springframework.data.jpa.repository.JpaRepository; public interface TaskRepository extends JpaRepository<Task, Long> { }

With this repository, Spring Data JPA will automatically generate CRUD (Create, Read, Update, Delete) operations for the Task entity.

1.4. Create a REST Controller

Next, create a TaskController in a controller package to expose REST endpoints that our frontend can interact with:

java
package com.example.demo.controller; import com.example.demo.model.Task; import com.example.demo.repository.TaskRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/tasks") public class TaskController { @Autowired private TaskRepository taskRepository; @GetMapping public List<Task> getAllTasks() { return taskRepository.findAll(); } @PostMapping public Task createTask(@RequestBody Task task) { return taskRepository.save(task); } @PutMapping("/{id}") public Task updateTask(@PathVariable Long id, @RequestBody Task task) { task.setId(id); return taskRepository.save(task); } @DeleteMapping("/{id}") public void deleteTask(@PathVariable Long id) { taskRepository.deleteById(id); } }

This controller exposes several endpoints:

  • GET /api/tasks: Get all tasks
  • POST /api/tasks: Create a new task
  • PUT /api/tasks/{id}: Update a task
  • DELETE /api/tasks/{id}: Delete a task

With this setup, our backend is ready! You can run the application by starting the main application class (usually DemoApplication.java) and testing the endpoints using Postman or cURL.

Step 2: Setting Up the React Frontend

Now that we have our backend ready, let’s move on to creating the frontend with React. We’ll use create-react-app to set up a simple React project.

2.1. Initialize Your React Project

Open a terminal, navigate to your desired directory, and run:

bash
npx create-react-app task-manager cd task-manager

Once the setup is complete, open the project in your code editor.

2.2. Install Axios

We’ll use Axios to make HTTP requests to our backend API. Install it by running:

bash
npm install axios

2.3. Create the Task Management Components

Now, let’s create some React components to display, create, and update tasks.

  1. Create a Services Folder: Inside src, create a new folder called services. Inside, create a file taskService.js to handle API calls.

    javascript
    import axios from 'axios'; const API_URL = 'http://localhost:8080/api/tasks'; export const getTasks = () => axios.get(API_URL); export const createTask = (task) => axios.post(API_URL, task); export const updateTask = (id, task) => axios.put(`${API_URL}/${id}`, task); export const deleteTask = (id) => axios.delete(`${API_URL}/${id}`);
  2. Create the TaskList Component: In src, create a components folder. Inside it, create TaskList.js to display tasks.

    javascript
    import React, { useEffect, useState } from 'react'; import { getTasks, createTask, updateTask, deleteTask } from '../services/taskService'; function TaskList() { const [tasks, setTasks] = useState([]); const [taskName, setTaskName] = useState(''); useEffect(() => { fetchTasks(); }, []); const fetchTasks = async () => { const response = await getTasks(); setTasks(response.data); }; const handleAddTask = async () => { const newTask = { name: taskName, completed: false }; await createTask(newTask); fetchTasks(); setTaskName(''); }; const handleToggleCompletion = async (task) => { await updateTask(task.id, { ...task, completed: !task.completed }); fetchTasks(); }; const handleDeleteTask = async (id) => { await deleteTask(id); fetchTasks(); }; return ( <div> <h1>Task Manager</h1> <input type="text" value={taskName} onChange={(e) => setTaskName(e.target.value)} placeholder="Add new task" /> <button onClick={handleAddTask}>Add Task</button> <ul> {tasks.map((task) => ( <li key={task.id}> <span style={{ textDecoration: task.completed ? 'line-through' : 'none', }} onClick={() => handleToggleCompletion(task)} > {task.name} </span> <button onClick={() => handleDeleteTask(task.id)}>Delete</button> </li> ))} </ul> </div> ); } export default TaskList;

This component fetches tasks from the backend, displays them, and allows users to add, toggle completion, and delete tasks.

2.4. Add TaskList to App.js

Finally, import TaskList in App.js and render it:

javascript
import React from 'react'; import './App.css'; import TaskList from './components/TaskList'; function App() { return ( <div className="App"> <TaskList /> </div> ); } export default App;

Step 3: Run and Test Your Full Stack Application

To see your app in action:

  1. Start the Spring Boot Backend: Run your Spring Boot application.

  2. Start the React Frontend: Open another terminal, navigate to the React project directory, and run:

    bash
    npm start

Your React app should now open in a browser, displaying the task manager UI that interacts with the Spring Boot backend. You can add, update, and delete tasks in real-time.

Wrapping Up

Congratulations! You’ve just built a full-stack Java application using Spring Boot and React. This setup is the foundation for a lot of modern web applications, giving you the flexibility of Java’s backend power and React’s dynamic front end. Once you’re comfortable with this setup, you can add more features like user authentication, advanced state management, or even containerization with Docker.

Happy coding, and enjoy building more full-stack applications!

Comments

Popular posts from this blog

10 AWS Services Every Developer Should Know in 2025

DevOps Course: What It Is, Why You Need It, and How to Get Started

From Beginner to Java Full Stack Expert: The Career Journey Explained