Hello everyone,

Greetings today!

Today we'll look at a common scenario, how to upload a file with JSON data to the Spring Boot Rest API. I have a form with some fields like name, number, etc which are sent to the server as JSON and the form has some fields where the user can upload a file, so I need to send the JSON data and the file to the server Suppose you have a single API call from the UI,

So let's start with

First, go to Spring Initializr and create the project structure as shown below

Then create a dto package and add the classes UserDTO.java,AddressProofDTO.java to this package. Here, UserDTO.java contains basic details of the user and AddressProofDTO.java contains multipart files and document types such as voter IDs.

AddressProofDTO.java

package com.user.mgt.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class AddressProofDTO {

    private MultipartFile file;

    private String documentType;

}

UserDTO.java

package com.user.mgt.dto;

import lombok.*;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
public class UserDTO {

    private String name;

    private String address;

    private String mobileNo;

    private AddressProofDTO addressProof;
}

Next, let's create a UserController.java with an endpoint for registering users. Since we got both the JSON data and the multipart file in one API call, we use @ModelAttribute instead of @RequestBody.

UserController.java

package com.user.mgt.controller;

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private RegistrationService registrationService;

    @PostMapping("register")
    public ResponseEntity<String> registerUser
    	(@ModelAttribute UserDTO userDTO){
        
        registrationService.registerUser(userDTO);
        return new ResponseEntity<>
        	("User registered successfully.",
            	HttpStatus.CREATED);
    }
}

I need to send both JSON+ and multipart files in a single API call using form data from postman as shown below.
The next step is to create a FileService that stores files in the file system. We're using the Windows file system to store the files here, but we'll provide an interface and implementation so that you can easily change the file storage system as needed.

FileService.java
package com.user.mgt.service;

import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Path;

public interface FileService {

    void saveFile(MultipartFile multipartFile, Path path);
}

WindowsFileServiceImpl.java
package com.user.mgt.service.impl;

import com.user.mgt.service.FileService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

@Service
public class WindowsFileServiceImpl implements FileService {
    @Override
    public void saveFile
    	(MultipartFile multipartFile, Path path) {
        
      try {
         File directory=new File(path.toString());
         if(!directory.exists())
              directory.mkdirs();
         Files.write
            (path.resolve(multipartFile.getOriginalFilename()),
			  multipartFile.getBytes());
        } catch (IOException e) {
            System.out.println("Error while storing file "+e);
        }
    }
}

The next step is to create a RegistrationService that stores basic user details and calls the file service to store the file. File uploads are the main focus of this article, so we won't create a repository layer to store basic user details.

RegistrationServiceImpl.java
package com.user.mgt.service.impl;

import com.user.mgt.dto.UserDTO;
import com.user.mgt.service.FileService;
import com.user.mgt.service.RegistrationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.file.Path;
import java.nio.file.Paths;

@Service
public class RegistrationServiceImpl 
		implements RegistrationService {

    @Autowired
    private FileService fileService;

    @Override
    public void registerUser(UserDTO userDTO) {
        //TODO Add code to store user basic details
        	like name, address etc

        // 2L should be replaced by dynamic user id
        	which will be generated after storing user details
     fileService.saveFile
       (userDTO.getAddressProof().getFile(),
           getFilePath("F:\\TEST",
             userDTO.getAddressProof().getDocumentType(),2L));
    }

    private Path getFilePath
    	(String basePath,String documentType,Long userId)
    {
        Path path= Paths.get(basePath);
        return path
        	.resolve(String.valueOf(userId))
            	.resolve(documentType);
    }
}

Here the getFilePath method creates a dynamic path based on the user id generated when saving the user details. Note that I used static 2 as the static user id.

So if your base path is F:\\document and your document type is VoterId, your path would be: F:\\document\\2\\VoterId\\my_voting_card.pdf

We've seen how to use the Spring Boot Rest API to upload files and JSON data in a single API call. If you have any questions, feel free to leave a comment.

Below is the project structure for reference.

Thanks
Enjoy your learning!



Another post you can refer to is


Backlink To Festival Images