In this tutorial, let’s create a real-time example of submitting complex form data with an image or file in Spring Boot, ReactJS, and Postman.
Handling form data is a fundamental task that developers frequently encounter. However, when it comes to submitting more complex data types like images or files, the process can become a tad intricate. Enter the trifecta of Spring Boot, ReactJS, and Postman—a powerful combination that simplifies this task by leveraging the strengths of each technology.
This guide aims to provide a step-by-step walkthrough, shedding light on how you can seamlessly submit form data, including images or files, using Spring Boot on the backend, ReactJS on the front end, and Postman for testing.
Quick Steps
- Create a Spring boot Project using the Spring tool initializer.
- Create an entity with the name “UploadEntity”.
- Create a JPA repository with the name “UploadRepository”.
- Create a Service Class name as “UploadService”.
- Create Controller class name as “UploadCtl”.
- Run the Project and access the API endpoints on Postman for testing.
Create an entity class
@Entity: This annotation indicates that the class is an entity, which means it’s a mapped class in the Java Persistence API (JPA). Entities are typically used to represent tables in a database.
@Table(name = “upload”): Specifies the table name in the database where this entity will be stored. In this case, the table name is “upload”.
@Setter and @Getter: These are Lombok annotations that automatically generate setter and getter methods for the class fields, respectively. Using Lombok reduces boilerplate code.
@Id: Indicates that the annotated field is the primary key of the entity.
@GeneratedValue(strategy = GenerationType.IDENTITY): Specifies that the primary key will be automatically generated by the database. The GenerationType.IDENTITY strategy is often used with databases like MySQL to auto-increment the primary key.
@Column(name = “Id”): Specifies the column name in the database table corresponding to this field. Here, the column name is “Id”.
private long id: Declares a private field named id of type long to store the primary key value.
@Column(name = “name”, length = 755): Indicates that the name field will be mapped to a column named “name” in the database table with a maximum length of 755 characters.
private String name: Declares a private field named name of type String to store the name value.
Similar to the name field, this part specifies that the type field will be mapped to a column named “type” in the database table with a maximum length of 755 characters.
private String type: Declares a private field named type of type String to store the type value.
@Column(name = “imageFile”, columnDefinition = “LONGBLOB”): Indicates that the imageFile field will be mapped to a column named “imageFile” in the database table. The columnDefinition = “LONGBLOB” part specifies that this column will store large binary data, often used for storing image files or other large binary objects.
private String imageFile: Declares a private field named imageFile of type String to store the binary data or reference to an image file.
UploadEntity.java
package io.hatchways.api.entity; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.Getter; import lombok.Setter; @Entity @Table(name = "upload") @Setter @Getter public class UploadEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "Id") private long id; @Column(name = "name", length = 755) private String name; @Column(name = "type", length = 755) private String type; @Column(name = "imageFile", columnDefinition = "LONGBLOB") private String imageFile; }
In summary, the UploadEntity class represents an entity that maps to a database table named “upload”. It contains fields for storing an ID (primary key), name, type, and image file data, each corresponding to specific columns in the database table. The use of annotations like @Entity, @Table, @Id, @Column, and Lombok’s @Setter and @Getter simplifies the entity mapping and reduces boilerplate code.
Create JPA Repository
public interface UploadRepository: This declares a public interface named UploadRepository. In the context of Spring Data JPA, repository interfaces are used to interact with the underlying database.
extends JpaRepository<UploadEntity, Long>: The UploadRepository interface extends the JpaRepository interface, which is a part of Spring Data JPA. By extending this interface, UploadRepository inherits several CRUD (Create, Read, Update, Delete) methods out-of-the-box without the need for manual implementation.
UploadEntity: Specifies the domain type that this repository manages, meaning it’s responsible for handling operations related to the UploadEntity class.
UploadEntity findById(long id): This method signature defines a custom query method in the UploadRepository interface.
findById: This is a convention-based query method provided by Spring Data JPA, which implies that it’s a method for finding an entity by its ID.
By having this findById method in the UploadRepository interface, you can easily fetch a UploadEntity object by its ID from the database without writing the query implementation. Under the hood, Spring Data JPA will generate the necessary SQL query based on the method name (findById) and return the corresponding UploadEntity object if found; otherwise, it will return null.
UploadRepository.java
package io.hatchways.api.repository; import org.springframework.data.jpa.repository.JpaRepository; import io.hatchways.api.entity.UploadEntity; public interface UploadRepository extends JpaRepository<UploadEntity, Long> { UploadEntity findById(long id); }
In summary, the UploadRepository interface serves as a repository interface for the UploadEntity class, inheriting CRUD methods from JpaRepository and defining a custom query method (findById) to fetch an entity by its ID.
Create a Service Class
@Service: This annotation is used to indicate that the UploadService class is a Spring service bean. Spring will automatically detect this class during the component scanning process and create a singleton instance of it, allowing you to inject it into other Spring-managed beans using dependency injection.
@Autowired: This annotation is used for automatic dependency injection. By annotating the repository field with @Autowired, Spring will automatically inject an instance of UploadRepository into this field when creating a UploadService bean, thus allowing UploadService to interact with the database through the repository.
public UploadEntity Add(UploadEntity entity): This method signature defines a public method named Add that takes an UploadEntity object (entity) as its parameter and returns an UploadEntity object.
UploadService.java
package io.hatchways.api.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import io.hatchways.api.entity.UploadEntity; import io.hatchways.api.repository.UploadRepository; @Service public class UploadService { @Autowired UploadRepository repository; public UploadEntity Add(UploadEntity entity) { return repository.save(entity); } }
UploadService class is a Spring service bean responsible for handling business logic related to UploadEntity objects. It utilizes the UploadRepository interface (which extends JpaRepository) for database operations.
The Add method within this service class uses the save method from the repository to persist an UploadEntity object into the database, either inserting a new record or updating an existing record based on the primary key value of the entity.
Create Controller
UploadCtl responsible for handling HTTP POST requests related to uploading files and associated data. Let’s delve into the code to understand its functionalities:
@RestController: This annotation combines the @Controller and @ResponseBody annotations. It indicates that the UploadCtl class is a Spring MVC controller that handles HTTP requests and produces a response in the form of JSON or XML.
@Autowired private ObjectMapper objectMapper;: The ObjectMapper is a Jackson library component used to convert between Java objects and JSON. Here, it’s injected into the objectMapper field, enabling the controller to deserialize JSON strings into UploadEntity objects.
@PostMapping(“/upload”): This annotation maps HTTP POST requests to the /upload endpoint to the add method in the controller.
@RequestParam(“imageFile”) MultipartFile imageFile and @RequestParam(“uploadData”) String upload: These annotations bind the request parameters imageFile and uploadData to the respective method parameters imageFile and upload.
MultipartFile imageFile: Represents the uploaded file data, enabling file handling operations.
String upload: Represents the JSON string containing additional data related to the upload, such as metadata for the UploadEntity.
UploadCtl.java
package io.hatchways.api.ctl; import java.io.IOException; import java.util.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.hatchways.api.entity.UploadEntity; import io.hatchways.api.service.PostService; import io.hatchways.api.service.UploadService; @RestController public class UploadCtl { @Autowired private UploadService service; @Autowired private ObjectMapper objectMapper; @CrossOrigin(origins = "http://localhost:3000/") @PostMapping("/upload") public UploadEntity add(@RequestParam("imageFile") MultipartFile imageFile, @RequestParam("uploadData") String upload) { UploadEntity uEntity = null; UploadEntity rEntity = null; String imageContent = null; try { uEntity = objectMapper.readValue(upload, UploadEntity.class); if(imageFile != null) { imageContent = Base64.getEncoder().encodeToString(imageFile.getBytes()); } uEntity.setImageFile(imageContent); rEntity = service.Add(uEntity); System.out.println("Entity is added............."); System.out.println("rEntity: "+rEntity); return rEntity; } catch (JsonMappingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JsonProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return rEntity; } }
In summary, the UploadCtl class defines a Spring Boot REST controller with a POST endpoint /upload. When a POST request is made to this endpoint with an imageFile and uploadData, the add method handles the request.
Output