Skip to content Skip to sidebar Skip to footer

Spring Boot Upload File and Insert Other Information to Database

1. Introduction

In this article, we will present how to create a Spring Kicking application that uploads a file to the PostgreSQL database. The server application based on REST compages will employ Spring Data JPA for executing queries on the database and MultipartFile interface for handling multi-role requests.

ii. Technology

Spring Boot application volition use the following technology stack:

  • Coffee 8
  • Spring Kicking 2
  • Spring Data JPA
  • PostgreSQL
  • Maven 3.6.i

3. Project structure

                ├── pom.xml ├── src │   ├── main │   │   ├── java │   │   │   └── com │   │   │       └── frontbackend │   │   │           └── springboot │   │   │               ├── Application.java │   │   │               ├── controller │   │   │               │   └── FilesController.coffee │   │   │               ├── exceptions │   │   │               │   └── RestExceptionHandler.java │   │   │               ├── model │   │   │               │   ├── FileEntity.java │   │   │               │   └── FileResponse.coffee │   │   │               ├── repository │   │   │               │   └── FileRepository.java │   │   │               └── service │   │   │                   └── FileService.java │   │   └── resources │   │       └── awarding.properties                              

Project contains:

  • FileEntity class that is a data model entity object related to a table in the PostgreSQL database,
  • FileResponse is a POJO object used to list files,
  • FileRepository is a Spring Data repository used to save and retrieve files to/from the database,
  • FileService is our service that will be calling methods from FileRepository,
  • FilesController used to handle HTTP requests like POST (for uploading files), GET (for listing and downloading files),
  • RestExceptionHandler class handles exceptions that could occur when processing requests,
  • application.backdrop is a Bound Boot configuration file used to setup database connection and set file upload size limits,
  • pom.xml for projection dependencies.

four. Residual API for uploading/downloading files

The Spring Kick application will provide a fully Balance-ful API for:

  • uploading files to PostgreSQL database,
  • downloading files from the database,
  • retrieving a list of uploaded files.

Leap Kicking awarding will provide the following API endpoints:

URL Method Activity
/files Go Become list of uploaded files
/files POST Upload a single file
/files/{uuid} GET Download uploaded file

Files will be downloaded directly to the database with informations like:

  • proper name of the file,
  • size of the file,
  • generated UUID to identify the uploaded file,
  • file content equally BLOB,
  • file content type.

5. Configure Spring Boot projection

First, we need to create a Leap Kicking project using initializer or with IDE like Eclipse, IntelliJ where nosotros can but create a new Maven project.

And so, we demand to add Jump Kick web and Bound JPA starter dependencies to our pom.xml file:

                <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://maven.apache.org/POM/four.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>iv.0.0</modelVersion>      <groupId>com.frontbackend.springboot</groupId>     <artifactId>upload-file-to-postgresql</artifactId>     <version>0.0.i-SNAPSHOT</version>      <!-- Inherit defaults from Bound Boot -->     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>bound-boot-starter-parent</artifactId>         <version>two.i.5.RELEASE</version>     </parent>      <!-- Add typical dependencies for a web application -->     <dependencies>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>bound-kick-starter-web</artifactId>         </dependency>         <dependency>             <groupId>org.springframework.kicking</groupId>             <artifactId>jump-kicking-starter-data-jpa</artifactId>         </dependency>         <dependency>             <groupId>org.postgresql</groupId>             <artifactId>postgresql</artifactId>             <version>42.2.eleven</version>             <telescopic>runtime</scope>         </dependency>     </dependencies>      <!-- Bundle equally an executable jar -->     <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>             </plugin>         </plugins>     </build>  </project>                              

The org.postgresql:postgresql library is used for interactions with the PostgreSQL database.

For the latest versions of this dependecies check the following links:

  • leap-boot-starter-spider web,
  • spring-boot-starter-data-jpa,
  • org.postgresql.

6. Create Model Entity

Entity objects correspond to database tables. In our projection nosotros created a FileEntity class that will be related to the FILES tabular array:

                bundle com.frontbackend.springboot.model;  import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Tabular array;  import org.hide.annotations.GenericGenerator;  @Entity @Table(proper name = "FILES") public class FileEntity {      @Id     @GeneratedValue(generator = "uuid")     @GenericGenerator(name = "uuid", strategy = "uuid2")     private String id;      private String proper noun;      private Cord contentType;      private Long size;      @Lob     individual byte[] data;      public String getId() {         return id;     }      public void setId(String id) {         this.id = id;     }      public Cord getName() {         return proper name;     }      public void setName(Cord proper name) {         this.proper name = name;     }      public String getContentType() {         return contentType;     }      public void setContentType(Cord contentType) {         this.contentType = contentType;     }      public Long getSize() {         return size;     }      public void setSize(Long size) {         this.size = size;     }      public byte[] getData() {         render data;     }      public void setData(byte[] information) {         this.data = data;     } }                              

Two fields were marked with special annotations:

  • id - @Id, @GeneratedValue(generator = "uuid"), @GenericGenerator(proper noun = "uuid", strategy = "uuid2") - this field will take auto-generated UUID,
  • data - @Lob special datatype that informs almost storing large objects in the database.

Second POJO class used in model layer is FileResponse:

                package com.frontbackend.springboot.model;  public class FileResponse {      private String id;     private String name;     individual Long size;     private String url;     private String contentType;      public String getId() {         return id;     }      public void setId(String id) {         this.id = id;     }      public String getName() {         render name;     }      public void setName(String name) {         this.name = proper noun;     }      public Long getSize() {         render size;     }      public void setSize(Long size) {         this.size = size;     }      public String getUrl() {         return url;     }      public void setUrl(String url) {         this.url = url;     }      public String getContentType() {         return contentType;     }      public void setContentType(String contentType) {         this.contentType = contentType;     } }                              

This object will be used to present a list of files with detailed information about them, such as name, content blazon, size.

7. Implement data access layer

In our data access layer, we take an interface FileRepository that extends JpaRepository. Cheers to this, we have access to crud methods like save(...), getById(...), delete(...) etc.

                parcel com.frontbackend.springboot.repository;  import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository;  import com.frontbackend.springboot.model.FileEntity;  @Repository public interface FileRepository extends JpaRepository<FileEntity, String> { }                              

8. Create service for managing files

The FileService class will be responsible for:

  • saving uploaded files (transforming MultipartFile object into FileEntity),
  • uploading a single file past provided id,
  • return a list of uploaded files.
                package com.frontbackend.springboot.service;  import java.io.IOException; import java.util.List; import java.util.Optional;  import org.springframework.beans.factory.note.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile;  import com.frontbackend.springboot.model.FileEntity; import com.frontbackend.springboot.repository.FileRepository;  @Service public class FileService {      private concluding FileRepository fileRepository;      @Autowired     public FileService(FileRepository fileRepository) {         this.fileRepository = fileRepository;     }      public void save(MultipartFile file) throws IOException {         FileEntity fileEntity = new FileEntity();         fileEntity.setName(StringUtils.cleanPath(file.getOriginalFilename()));         fileEntity.setContentType(file.getContentType());         fileEntity.setData(file.getBytes());         fileEntity.setSize(file.getSize());          fileRepository.save(fileEntity);     }      public Optional<FileEntity> getFile(String id) {         render fileRepository.findById(id);     }      public List<FileEntity> getAllFiles() {         return fileRepository.findAll();     } }                              

In most cases FileService just calls methods from FileRepository only it is a good place for future business organization logic.

9. Create a Residual controller for handing HTTP requests

The FilesController will exist responsible for handling HTTP requests.

This course has been marked with the following annotations:

  • @RestController - annotation is used to treat this grade as a Balance controller,
  • @RequestMapping - create a base of operations endpoint to /files URI.

Other annotations used in this class like @GetMapping, @PostMapping and @DeleteMapping - are for mapping HTTP Become, POST and DELETE requests with specific class methods:

HTTP Method Endpoint Method
POST /files upload(...)
GET /files list(...)
GET /files/{id} getFile(...)
                parcel com.frontbackend.springboot.controller;  import coffee.util.List; import java.util.Optional; import java.util.stream.Collectors;  import org.springframework.beans.factory.notation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.spider web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.notation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.spider web.bind.annotation.RequestParam; import org.springframework.spider web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.support.ServletUriComponentsBuilder;  import com.frontbackend.springboot.model.FileEntity; import com.frontbackend.springboot.model.FileResponse; import com.frontbackend.springboot.service.FileService;  @RestController @RequestMapping("files") public form FilesController {      private final FileService fileService;      @Autowired     public FilesController(FileService fileService) {         this.fileService = fileService;     }      @PostMapping     public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file) {         try {             fileService.save(file);              return ResponseEntity.condition(HttpStatus.OK)                                  .body(Cord.format("File uploaded successfully: %s", file.getOriginalFilename()));         } catch (Exception e) {             render ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)                                  .body(String.format("Could non upload the file: %s!", file.getOriginalFilename()));         }     }      @GetMapping     public List<FileResponse> list() {         return fileService.getAllFiles()                           .stream()                           .map(this::mapToFileResponse)                           .collect(Collectors.toList());     }      private FileResponse mapToFileResponse(FileEntity fileEntity) {         String downloadURL = ServletUriComponentsBuilder.fromCurrentContextPath()                                                         .path("/files/")                                                         .path(fileEntity.getId())                                                         .toUriString();         FileResponse fileResponse = new FileResponse();         fileResponse.setId(fileEntity.getId());         fileResponse.setName(fileEntity.getName());         fileResponse.setContentType(fileEntity.getContentType());         fileResponse.setSize(fileEntity.getSize());         fileResponse.setUrl(downloadURL);          render fileResponse;     }      @GetMapping("{id}")     public ResponseEntity<byte[]> getFile(@PathVariable String id) {         Optional<FileEntity> fileEntityOptional = fileService.getFile(id);          if (!fileEntityOptional.isPresent()) {             return ResponseEntity.notFound()                                  .build();         }          FileEntity fileEntity = fileEntityOptional.get();         return ResponseEntity.ok()                              .header(HttpHeaders.CONTENT_DISPOSITION, "zipper; filename=\"" + fileEntity.getName() + "\"")                              .contentType(MediaType.valueOf(fileEntity.getContentType()))                              .torso(fileEntity.getData());     } }                              

x. Configure JPA, Hibernate and file size upload limits

In the application.properties file we created a several entries:

                leap.datasource.url=jdbc:postgresql://localhost:5432/testdb spring.datasource.username=username leap.datasource.password=countersign  spring.jpa.backdrop.hibernate.jdbc.lob.non_contextual_creation=truthful spring.jpa.backdrop.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect  spring.jpa.hibernate.ddl-auto=create  spring.servlet.multipart.max-file-size=1MB spring.servlet.multipart.max-asking-size=1MB                              

Nosotros used the following properties:

  • bound.datasource.url - to ascertain a datasource,
  • bound.datasource.username - database username,
  • jump.datasource.countersign - database password,
  • spring.jpa.hibernate.ddl-auto tin be:
    • none - no change is made to the database construction,
    • update - Hide volition change the database according to the given entity structures,
    • create - this will creates the database every time on server start,
    • create-driblet - creates the database and drops it when SessionFactory closes.
  • bound.servlet.multipart.max-file-size - maximum file size for each asking.
  • spring.servlet.multipart.max-request-size - maximum size for a multipart requests.

xi. Create exception handler

The class annotated with @ControllerAdvice is responsible for handling exceptions that may occur during the uploading files process:

                package com.frontbackend.springboot.exceptions;  import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;  @ControllerAdvice public class RestExceptionHandler extends ResponseEntityExceptionHandler {      @ExceptionHandler(MaxUploadSizeExceededException.grade)     public ResponseEntity<String> handleMaxSizeException(MaxUploadSizeExceededException exc) {         return ResponseEntity.condition(HttpStatus.BAD_REQUEST)                              .body("Unable to upload. File is too large!");     } }                              

We handle just MaxUploadSizeExceededException but this could be extended to some other exceptions too.

12. Primary Spring Kick starting server class

The chief Jump Boot application form that starts the server has the following structure:

                parcel com.frontbackend.springboot;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.spider web.demark.annotation.RestController;  @SpringBootApplication @RestController public class Application {      public static void main(String[] args) {         SpringApplication.run(Application.grade, args);     } }                              

13. Testing Application API

To run the Spring Kick server employ mvn leap-kick:run control or find the generated jar in the /target folder and type java -jar upload-file-to-postgresql-0.0.1-SNAPSHOT.jar.

When everything is correctly configured You should see information virtually the started server:

                INFO 27542 --- [           primary] com.frontbackend.springboot.Awarding  : Started Application in 2.929 seconds (JVM running for 3.312)                              

Besides in the database, there should exist a new table called FILES with the post-obit structure:

Upload file to postgresql diagram

Nosotros will employ Postman to make some API requests.

13.ane. Outset, permit'due south upload some file

Upload file to db

In the FILES table a new tape appeared:

Upload file to postgresql uploaded db

13.ii. Now check a list of uploaded files

Get list of files from db

13.3. Finally, download the upload file using a provided URL

Download file from db

14. Conclusion

In this tutorial, nosotros presented step past step how to create a Spring Boot application that will upload files to the PostgreSQL database.

As usual, the code used in this tutorial is bachelor in our GitHub repository.

paynetakintime.blogspot.com

Source: https://frontbackend.com/spring-boot/spring-boot-upload-file-to-postgresql-database

Post a Comment for "Spring Boot Upload File and Insert Other Information to Database"