Skip to content

guilhermeborgesbastos/Spring-Boot-Studies

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 

Repository files navigation

Spring Boot Studies Awesome

This repository keeps evolving as I continue covering more functionalities and techniques from Spring boot application.

A generic repository for study purposes, with all the exercises from the https://www.tutorialspoint.com/spring_boot

Get back to the main Summary Page.

Spring Boot Studies - File Handling By Guilherme Borges Bastos

Spring Boot - File Handling

In this chapter, we will learn how to upload and download files by using a Web Service. A UI Interface was also created using the MVC application design model.

Upload

File Handling - Upload Simple User Interface

Download

File Handling - Download Simple User Interface

File Uploading

For uploading a file, we can use MultipartFile as a Request Parameter and this API should consume Multi-Part form data value.

Let's start by creating the Service layer −

Service Layer

@Service
public class FileUploadService implements IFileUpload{

  @Value("${multipart.location}")
  private String uploadTempDir;

  /**
   * Uploads the file using the multipart location property located in the application.properties
   * file.
   * 
   * @param file
   * @throws IOException
   * @throws FileNotFoundException
   */
  private void writeFile(MultipartFile file) throws IOException, FileNotFoundException {
    final File convertFile = new File(uploadTempDir + file.getOriginalFilename());
    convertFile.createNewFile();
    final FileOutputStream fileOut = new FileOutputStream(convertFile);
    fileOut.write(file.getBytes());
    fileOut.close();
  }

  /**
   * Uploads a single file.
   *
   * @param file
   * @return the boolean true, if succeed.
   * @throws IOException Signals that an I/O exception has occurred.
   */
  public Boolean uploadFile(MultipartFile file) throws IOException {
    writeFile(file);
    return true;
  }

  /**
   * Uploads multiple files.
   *
   * @param files
   * @return the boolean true, if succeed.
   * @throws IOException Signals that an I/O exception has occurred.
   */
  public Boolean uploadMultiFile(MultipartFile[] files) throws IOException {
    for (MultipartFile file : files) {
      writeFile(file);
    }
    return true;
  }
}

After creating the service layer it's time to work on the @Controller -

Controller Layer

All the static resources used on the User Interface are available at this link.

Below is the controller's code -

package com.gbastos.FileHandlerWebService.controller;

import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.gbastos.FileHandlerWebService.model.FormDataWithFile;
import com.gbastos.FileHandlerWebService.service.FileUploadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class FileUploadController it is a simple sample of a Web Service used to handle Filed on
 * Spring Boot.
 */
@Controller
@RequestMapping("/upload")
public class FileUploadController {

  private static final Logger LOG = LoggerFactory.getLogger(FileUploadController.class);
  private static final String REQUEST_URI = "requestURI";

  @Autowired
  private FileUploadService fileUploadService;

  @GetMapping(value = "/")
  public String displayForm() {
    return "fileUploadForm";
  }

  @PostMapping(value = "/uploadFile")
  public String submit(@RequestParam("file") final MultipartFile file, final ModelMap modelMap) {

    try {
      fileUploadService.uploadFile(file);
    } catch (IOException e) {
      LOG.error(e.getMessage(), e.getCause());
    }

    modelMap.addAttribute("file", file);
    modelMap.addAttribute(REQUEST_URI, "uploadFile");
    return "fileUploadView";
  }

  @PostMapping(value = "/uploadMultiFile")
  public String submit(@RequestParam("files") final MultipartFile[] files,
      final ModelMap modelMap) {

    try {
      fileUploadService.uploadMultiFile(files);
    } catch (IOException e) {
      LOG.error(e.getMessage(), e.getCause());
    }

    modelMap.addAttribute("files", files);
    modelMap.addAttribute(REQUEST_URI, "uploadMultiFile");
    return "fileUploadView";
  }

  @PostMapping(value = "/uploadFileWithAdditionalData")
  public String submit(@RequestParam final MultipartFile file, @RequestParam final String name,
      @RequestParam final String email, final ModelMap modelMap) {

    try {
      fileUploadService.uploadFile(file);
    } catch (IOException e) {
      LOG.error(e.getMessage(), e.getCause());
    }

    modelMap.addAttribute("name", name);
    modelMap.addAttribute("email", email);
    modelMap.addAttribute("file", file);
    modelMap.addAttribute(REQUEST_URI, "uploadFileWithAdditionalData");
    
    return "fileUploadView";
  }

  @PostMapping(value = "/uploadFileModelAttribute")
  public String submit(@ModelAttribute final FormDataWithFile formDataWithFile,
      final ModelMap modelMap) {

    try {
      fileUploadService.uploadFile(formDataWithFile.getFile());
    } catch (IOException e) {
      LOG.error(e.getMessage(), e.getCause());
    }

    modelMap.addAttribute("formDataWithFile", formDataWithFile);
    modelMap.addAttribute(REQUEST_URI, "uploadFileModelAttribute");
    return "fileUploadView";
  }
}

File Downloading

For file download, you should use InputStreamResource for downloading a File. We need to set the HttpHeader Content-Disposition in the Response and need to specify the response Media Type of the application. To do that, since there are several different Media Types we need to create a utilitary method to do that -

  /**
   * Retrieve mime type from file.
   *
   * @param file
   * @return the MIME type
   * @throws IOException Signals that an I/O exception has occurred.
   * @throws MalformedURLException the malformed URL exception
   */
  private String retrieveMimeTypeFromFile(File file) throws IOException, MalformedURLException {
    URLConnection connection = file.toURL().openConnection();
    String mimeType = connection.getContentType();

    return mimeType;
  }

Once the utilitary method is done, it's time to create the method into the Service layer that will output the downloaded file -

  /**
   * Download file based on the file's name.
   *
   * @param fileName
   * @return the response entity
   * @throws MalformedURLException the malformed URL exception
   * @throws IOException Signals that an I/O exception has occurred.
   */
  public ResponseEntity<Object> downloadFile(String fileName)
      throws MalformedURLException, IOException {

    final String filePath = uploadTempDir + fileName;
    final File file = new File(filePath);

    final InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
    final HttpHeaders headers = new HttpHeaders();

    headers.add("Content-Disposition",
        String.format("attachment; filename=\"%s\"", file.getName()));
    headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
    headers.add("Pragma", "no-cache");
    headers.add("Expires", "0");

    final String mimeType = retrieveMimeTypeFromFile(file);

    ResponseEntity<Object> responseEntity =
        ResponseEntity.ok().headers(headers).contentLength(file.length())
            .contentType(MediaType.parseMediaType(mimeType)).body(resource);

    return responseEntity;
  }

NoteIn the following example, file should be available on the specified path where the application is running.

In our front-end we have a Dropdown that is loaded with the names of all the files that were uploaded through your application, in order to do that, we need to create the service for it, this service will be injected and used in the controller further on at this example -

  /**
   * Fetches the file names that are placed on the storage.
   *
   * @return the list of file's names
   */
  public List<String> fetchFileNamesFromStorage() {

    final File folder = new File(uploadTempDir);
    final File[] listOfFiles = folder.listFiles();

    final List<String> fileNames = new ArrayList<String>();

    for (int i = 0; i < listOfFiles.length; i++) {

      if (listOfFiles[i].isFile()) {
        fileNames.add(listOfFiles[i].getName());
      }
    }

    return fileNames;
  }

The complete class can be found at this link.

After creating the service layer it's time to work on the @Controller -

Controller Layer

All the static resources used on the User Interface are available at this link.

Below is the controller's code -

package com.gbastos.FileHandlerWebService.controller;

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.gbastos.FileHandlerWebService.service.FileDownloadService;

/**
 * The Class FileDownloadController it is a simple sample of a Web Service used to handle Files on
 * Spring Boot.
 */
@Controller
@RequestMapping("/download")
public class FileDownloadController {

  private static final Logger LOG = LoggerFactory.getLogger(FileDownloadController.class);

  @Autowired
  private FileDownloadService fileDownloadService;
  
  @GetMapping(value = "/")
  public String displayForm(final ModelMap modelMap) {
    final List<String> fileNames = fileDownloadService.fetchFileNamesFromStorage();
    modelMap.addAttribute("files", fileNames);
    
    return "fileDownloadForm";
  }
  
  @RequestMapping(value = "/file", method = RequestMethod.POST) 
  public ResponseEntity<Object> downloadFile(@RequestParam("fileName") final String fileName) {
    
    ResponseEntity<Object> responseEntity = null;
    
    try {
      responseEntity = fileDownloadService.downloadFile(fileName);
    } catch (Exception e) {
      LOG.error(e.getMessage(), e.getCause());
    }

    return responseEntity;
  }
}

About

A generic repository for study purposes, with all the exercises from the https://www.tutorialspoint.com/spring_boot

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages