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.
- 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.
- 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.
- Click Generate to download the project zip file.
- Extract the zip file to your desired location.
- Open your IDE and import the project as a Maven project.
2.Configure Project Metadata:
3.1Select Dependenciesz:
4.Generate the Project:
5.Open the Project in Your IDE:
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.