Handling CORS in Spring Boot React JS Application

Author: Sai K

When developing a full-stack application with React as the frontend and Spring Boot as the backend, one

common issue developers encounter is CORS (Cross-Origin Resource Sharing). CORS is a security feature

implemented by browsers to prevent malicious websites from making requests to a different domain than the

one that served the web page. This article will guide you through handling CORS issues in a React JS 18 and

Spring Boot 3 application.


What is CORS?

CORS is a security feature implemented by browsers to prevent JavaScript from making requests across domain

boundaries. It allows a server to specify who can access its resources and how those resources can be

accessed. When the frontend (React) and backend (Spring Boot) are running on different origins (different

domains, ports, or schemes), the browser blocks the cross-origin requests unless the server explicitly

allows them.

Setting Up the Project

Spring Boot Backend

First, let’s set up a Spring Boot 3 application. We will create a simple REST API to manage products.

Step 1: Create a Spring Boot Project

Open Spring Initializr:

  • Go to Spring Initializr in your web browser.

  • 2.Configure Project Metadata:


    • Project: Maven Project

    • Language: Java

    • Spring Boot: Select the latest version of Spring Boot 3

    • Group: com.example

    • Artifact: spring-boot-react-cors

    • Name: spring-boot-react-cors

    • Description: Handling CORS in React and Spring Boot

    • Package Name: com.example.springbootreactcors

    • Packaging: Jar

    • Java Version: 17 (or your preferred version)

    • Click Next.

    3.1Select Dependenciesz:

    • On the Dependencies screen, select the dependencies you need:

      • Spring Web

      • Spring Data JPA

      • PostgreSQL Driver (or H2 for simplicity)

      • Spring Boot DevTools

    • Click Next.

    4.Generate the Project:

    • Click Generate to download the project zip file.

    • Extract the zip file to your desired location.

    5.Open the Project in Your IDE:

    • Open your IDE and import the project as a Maven project.

Step 2: Update application.properties

Open the application.properties file located in the src/main/resources directory and add the

following configuration:


spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=yourusername
spring.datasource.password=yourpassword

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

Replace yourusername and yourpassword with your PostgreSQL username and password, and testdb with your database name.

Step 3: Create the Product Entity

In the com.example.springbootreactcors.model package, create a new Java class named Product:


package com.example.springbootreactcors.model;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    // Getters and Setters
}
   

Step 4: Create the Product Repository

In the com.example.springbootreactcors.repository package, create a new Java interface named ProductRepository:


package com.example.springbootreactcors.repository;

import com.example.springbootreactcors.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository {
}
    

Step 5: Create the Product Service

In the com.example.springbootreactcors.service package, create a new Java class named ProductService:


package com.example.springbootreactcors.service;

import com.example.springbootreactcors.model.Product;
import com.example.springbootreactcors.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProductService {

    private final ProductRepository productRepository;

    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public List getAllProducts() {
        return productRepository.findAll();
    }

    public Product saveProduct(Product product) {
        return productRepository.save(product);
    }

    public Product getProductById(Long id) {
        return productRepository.findById(id).orElse(null);
    }
}
  

Step 6: Create the Product Controller

In the com.example.springbootreactcors.controller package, create a new Java class named ProductController:


package com.example.springbootreactcors.controller;

import com.example.springbootreactcors.model.Product;
import com.example.springbootreactcors.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/products")
@CrossOrigin(origins = "http://localhost:3000")
public class ProductController {

    private final ProductService productService;

    @Autowired
    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping
    public List getAllProducts() {
        return productService.getAllProducts();
    }

    @PostMapping
    public Product saveProduct(@RequestBody Product product) {
        return productService.saveProduct(product);
    }

    @GetMapping("/{id}")
    public Product getProductById(@PathVariable Long id) {
        return productService.getProductById(id);
    }
}
   

React Frontend

Next, let’s set up the React frontend application.

Step 1: Create a React Project

Open a terminal and navigate to your workspace directory.


npx create-react-app react-frontend
cd react-frontend
     

Step 2: Install Axios and Bootstrap


npm install axios bootstrap
     

Step 3: Create Product Service

Create a new file ProductService.js in the src directory to handle API requests for products:


import axios from 'axios';

const API_BASE_URL = "http://localhost:8080/products";

class ProductService {
    getAllProducts() {
        return axios.get(API_BASE_URL, {
            headers: {
                'Content-Type': 'application/json'
            },
            withCredentials: true
        });
    }

    getProductById(productId) {
        return axios.get(`${API_BASE_URL}/${productId}`, {
            headers: {
                'Content-Type': 'application/json'
            },
            withCredentials: true
        });
    }

    createProduct(product) {
        return axios.post(API_BASE_URL, product, {
            headers: {
                'Content-Type': 'application/json'
            },
            withCredentials: true
        });
    }
}

export default new ProductService();
        

Step 4: Create Components

ProductListComponent.js

Create a new file ProductListComponent.js in the src/components directory:


import React, { useEffect, useState } from 'react';
import ProductService from '../ProductService';
import 'bootstrap/dist/css/bootstrap.min.css';

const ProductListComponent = () => {
    const [products, setProducts] = useState([]);

    useEffect(() => {
        ProductService.getAllProducts().then((response) => {
            setProducts(response.data);
        });
    }, []);

    return (
        < div className="container mt-5">
            < h2>Products< /h2>
            < ul className="list-group">
                {products.map(product => (
                    < li key={product.id} className="list-group-item">
                        {product.name} - ${product.price}
                    < /li>
                ))}
            < /ul>
        < /div>
    );
};

export default ProductListComponent;
  

AddProductComponent.js

Create a new file AddProductComponent.js in the src/components directory:

App.js

Modify the App.js file to include routing for the components:

index.js

Ensure the index.js file is set up correctly:


import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    < React.StrictMode>
        < App />
    < /React.StrictMode>
);
    

Running the Application

Run the Spring Boot Application

Open the SpringBootReactCorsApplication class in the src/main/java/com/example/springbootreactcors directory.


./mvnw spring-boot:run
    

Run the React Application

Open a terminal and navigate to the react-frontend directory.


npm start
 

Open your web browser and navigate to http://localhost:3000.

You should now be able to make API requests from your React frontend to your Spring Boot backend without

encountering CORS issues.

Conclusion

Handling CORS in a React and Spring Boot application involves configuring the backend to allow requests from

the frontend. This can be done using the @CrossOrigin annotation on specific controllers or

configuring global CORS settings in a Spring configuration class. By following this tutorial, you can ensure

smooth communication between your React frontend and Spring Boot backend.

Related Spring and Spring Boot Tutorials/Guides: