Upload Files to Database With Rest Api
In this tutorial, I will evidence you lot how to upload and download files to/from database with a Leap Boot Rest APIs. We also use Bound Web MultipartFile
interface to handle HTTP multi-role requests.
This Leap Boot App works with:
– Angular 8 Client / Angular 10 Client / Angular eleven Customer / Athwart 12
– Angular Material 12
– Vue Customer / Vuetify Client
– React Client / React Hooks Customer
– Fabric UI Client
– Axios Client
Related Posts:
– How to upload multiple files in Java Spring Boot
– Leap Boot: Upload/Import Excel file data into MySQL Database
– Spring Boot: Upload/Import CSV file data into MySQL Database
Deployment:
– Deploy Spring Kicking App on AWS – Elastic Beanstalk
– Docker Compose: Spring Boot and MySQL example
Spring Boot Balance APIs for uploading Files to Database
Our Spring Boot Application volition provide APIs for:
- uploading File to PostgreSQL/MySQL database
- downloading File database with the link
- getting list of Files' information (file name, url, type, size)
These are APIs to be exported:
Methods | Urls | Deportment |
---|---|---|
POST | /upload | upload a File |
Go | /files | get Listing of Files (name, url, type, size) |
GET | /files/[fileId] | download a File |
The uploaded files volition be stored in PostgreSQL/MySQL Database files table with these fields: id
, name
, type
and data
as Blob blazon (Binary Big Object is for storing binary information like file, epitome, audio, or video).
Technology
- Java viii
- Spring Kicking two (with Leap Web MVC)
- PostgreSQL/MySQL Database
- Maven 3.6.1
Projection Structure
Allow me explain it briefly.
– FileDB
is the data model respective to files tabular array in database.
– FileDBRepository
extends Jump Data JpaRepository
which has methods to shop and retrieve files.
– FilesStorageService
uses FileDBRepository
to provide methods for saving new file, get file by id, get list of Files.
– FilesController
uses FilesStorageService
to export Rest APIs: Mail service a file, GET all files' information, download a File.
– FileUploadExceptionAdvice
handles exception when the controller processes file upload.
– ResponseFile
contains information of the file (name, url, type, size) for HTTP response payload.
– application.properties contains configuration for Servlet Multipart and PostgreSQL/MySQL database connection.
– pom.xml for Jump Boot, Spring Information JPA and PostgreSQL/MySQL connector dependency.
Setup Spring Kick project
Use Spring web tool or your development tool (Spring Tool Suite, Eclipse, Intellij) to create a Spring Boot project.
Then open pom.xml and add these dependencies:
<dependency> <groupId>org.springframework.kick</groupId> <artifactId>spring-boot-starter-spider web</artifactId> </dependency> <dependency> <groupId>org.springframework.kick</groupId> <artifactId>spring-kicking-starter-data-jpa</artifactId> </dependency>
We besides need to add together one more dependency.
– If you want to use MySQL:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</telescopic> </dependency>
– or PostgreSQL:
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</telescopic> </dependency>
Create Data Model
This Data Model is for storing File Information. At that place are 4 fields:
-
id
: automatically generated as UUID -
name
: proper name of the file -
blazon
: mime type -
data
: array of bytes, map to a BLOB
model/FileDB.java
package com.bezkoder.spring.files.upload.db.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "files") public class FileDB { @Id @GeneratedValue(generator = "uuid") @GenericGenerator(proper name = "uuid", strategy = "uuid2") private String id; private String name; private String type; @Lob private byte[] data; public FileDB() { } public FileDB(String name, String type, byte[] data) { this.name = proper name; this.type = type; this.data = data; } public Cord getId() { render id; } public String getName() { return name; } public void setName(String name) { this.proper noun = name; } public String getType() { return type; } public void setType(String blazon) { this.type = type; } public byte[] getData() { return data; } public void setData(byte[] information) { this.data = data; } }
In the code in a higher place, data
is annotated past @Lob
annotation. LOB is datatype for storing large object information. There're two kinds of LOB: Hulk and CLOB:
- Blob is for storing binary data
- CLOB is for storing text information
Create Repository
Under repository package, create FileDBRepository
interface that extends JpaRepository
.
repository/FileDBRepository.java
packet com.bezkoder.spring.files.upload.db.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.bezkoder.spring.files.upload.db.model.FileDB; @Repository public interface FileDBRepository extends JpaRepository<FileDB, Cord> { }
Now nosotros can utilize FileDBRepository
with JpaRepository
'due south methods such as: save(FileDB)
, findById(id)
, findAll()
.
Create Service for File Storage
The File Storage Service will utilise FileDBRepository
to provide post-obit methods:
-
store(file)
: receivesMultipartFile
object, transform toFileDB
object and salve it to Database -
getFile(id)
: returns aFileDB
object past provided Id -
getAllFiles()
: returns all stored files as list of code>FileDB objects
service/FileStorageService.java
package com.bezkoder.bound.files.upload.db.service; import java.io.IOException; import java.util.stream.Stream; import org.springframework.beans.manufactory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import com.bezkoder.spring.files.upload.db.model.FileDB; import com.bezkoder.bound.files.upload.db.repository.FileDBRepository; @Service public class FileStorageService { @Autowired private FileDBRepository fileDBRepository; public FileDB shop(MultipartFile file) throws IOException { String fileName = StringUtils.cleanPath(file.getOriginalFilename()); FileDB FileDB = new FileDB(fileName, file.getContentType(), file.getBytes()); return fileDBRepository.save(FileDB); } public FileDB getFile(String id) { return fileDBRepository.findById(id).get(); } public Stream<FileDB> getAllFiles() { return fileDBRepository.findAll().stream(); } }
Define Response Data Classes
Let's create two classes in message package. The controller volition use these classes for sending message via HTTP responses.
-
ResponseFile
: contains proper noun, url, type, size -
ResponseMessage
for notification/data message
bulletin/ResponseFile.java
packet com.bezkoder.leap.files.upload.db.bulletin; public course ResponseFile { private String proper name; private Cord url; individual String blazon; private long size; public ResponseFile(String name, String url, String type, long size) { this.proper name = proper name; this.url = url; this.type = type; this.size = size; } public String getName() { return name; } public void setName(String proper noun) { this.name = proper noun; } public Cord getUrl() { return url; } public void setUrl(Cord url) { this.url = url; } public String getType() { render type; } public void setType(Cord blazon) { this.type = type; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } }
message/ResponseMessage.java
packet com.bezkoder.spring.files.upload.db.message; public class ResponseMessage { private String message; public ResponseMessage(String message) { this.bulletin = message; } public Cord getMessage() { return message; } public void setMessage(Cord message) { this.bulletin = message; } }
Create Controller for upload & download Files to Database
In controller parcel, we create FileController
class.
controller/FileController.coffee
package com.bezkoder.spring.files.upload.db.controller; import java.util.List; import coffee.util.stream.Collectors; import org.springframework.beans.manufactory.note.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.spider web.bind.notation.CrossOrigin; import org.springframework.web.demark.annotation.GetMapping; import org.springframework.web.bind.notation.PathVariable; import org.springframework.spider web.bind.annotation.PostMapping; import org.springframework.web.bind.notation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import com.bezkoder.spring.files.upload.db.service.FileStorageService; import com.bezkoder.spring.files.upload.db.message.ResponseFile; import com.bezkoder.spring.files.upload.db.message.ResponseMessage; import com.bezkoder.spring.files.upload.db.model.FileDB; @Controller @CrossOrigin("http://localhost:8081") public class FileController { @Autowired private FileStorageService storageService; @PostMapping("/upload") public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file) { Cord message = ""; try { storageService.shop(file); message = "Uploaded the file successfully: " + file.getOriginalFilename(); return ResponseEntity.status(HttpStatus.OK).torso(new ResponseMessage(message)); } take hold of (Exception e) { message = "Could not upload the file: " + file.getOriginalFilename() + "!"; return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).trunk(new ResponseMessage(message)); } } @GetMapping("/files") public ResponseEntity<Listing<ResponseFile>> getListFiles() { List<ResponseFile> files = storageService.getAllFiles().map(dbFile -> { String fileDownloadUri = ServletUriComponentsBuilder .fromCurrentContextPath() .path("/files/") .path(dbFile.getId()) .toUriString(); return new ResponseFile( dbFile.getName(), fileDownloadUri, dbFile.getType(), dbFile.getData().length); }).collect(Collectors.toList()); return ResponseEntity.status(HttpStatus.OK).body(files); } @GetMapping("/files/{id}") public ResponseEntity<byte[]> getFile(@PathVariable String id) { FileDB fileDB = storageService.getFile(id); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileDB.getName() + "\"") .body(fileDB.getData()); } }
– @CrossOrigin
is for configuring allowed origins.
– @Controller
annotation is used to define a controller.
– @GetMapping
and @PostMapping
note is for mapping HTTP GET & POST requests onto specific handler methods:
- POST /upload:
uploadFile()
- Become /files:
getListFiles()
- Go /files/[id]:
getFile()
– We employ @Autowired
to inject implementation of FileStorageService
bean to local variable.
Configure Spring Datasource, JPA, Hibernate
Nether src/main/resources folder, open application.properties and write these lines.
– For MySQL:
leap.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=fake leap.datasource.username= root spring.datasource.password= 123456 spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect # Hide ddl auto (create, create-drop, validate, update) spring.jpa.hibernate.ddl-automobile= update
– For PostgreSQL:
bound.datasource.url= jdbc:postgresql://localhost:5432/testdb spring.datasource.username= postgres leap.datasource.password= 123 spring.jpa.properties.hide.jdbc.lob.non_contextual_creation= true spring.jpa.properties.hide.dialect= org.hibernate.dialect.PostgreSQLDialect # Hibernate ddl automobile (create, create-drib, validate, update) spring.jpa.hibernate.ddl-auto= update
-
spring.datasource.username
&spring.datasource.countersign
backdrop are the same as your database installation. - Bound Kick uses Hibernate for JPA implementation, we configure
MySQL5InnoDBDialect
for MySQL orPostgreSQLDialect
for PostgreSQL -
spring.jpa.hibernate.ddl-car
is used for database initialization. Nosotros set up the value toupdate
value then that a table volition be created in the database automatically respective to defined information model. Whatever change to the model will also trigger an update to the table. For product, this holding should existvalidate
.
Configure Multipart File for Servlet
Let'southward define the maximum file size that tin be uploaded in application.properties as post-obit:
spring.servlet.multipart.max-file-size=2MB spring.servlet.multipart.max-asking-size=2MB
– spring.servlet.multipart.max-file-size
: max file size for each asking.
– spring.servlet.multipart.max-request-size
: max request size for a multipart/form-data.
Handle File Upload Exception
This is where nosotros handle the case in that a request exceeds Max Upload Size. The system volition throw MaxUploadSizeExceededException
and nosotros're gonna use @ControllerAdvice
with @ExceptionHandler
annotation for handling the exceptions.
exception/FileUploadExceptionAdvice.java
package com.bezkoder.spring.files.upload.db.exception; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.spider web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.mvc.method.notation.ResponseEntityExceptionHandler; import com.bezkoder.spring.files.upload.db.bulletin.ResponseMessage; @ControllerAdvice public grade FileUploadExceptionAdvice extends ResponseEntityExceptionHandler { @ExceptionHandler(MaxUploadSizeExceededException.form) public ResponseEntity<ResponseMessage> handleMaxSizeException(MaxUploadSizeExceededException exc) { return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage("File too large!")); } }
Run & Test
Run Spring Kicking application with command: mvn spring-kicking:run
.
Let's use Postman to make some requests.
– Upload some files:
– Upload a file with size larger than max file size (2MB):
– Cheque files table in Database:
– Call up listing of Files' information:
– Now yous can download whatsoever file from one of the paths above.
For example: http://localhost:8080/files/6ba3578c-ce22-4dd7-999e-72192bf31b53
Conclusion
Today we've learned how to create Spring Boot Application to upload multipart files and get files' information with static folder via Restful API.
Following tutorials explain how to build Forepart-end Apps to work with our Bound Boot Server:
– Angular 8 Client / Angular 10 Customer / Angular 11 Client / Athwart 12
– Angular Fabric 12
– Vue Client / Vuetify Customer
– React Client / React Hooks Customer
– Cloth UI Client
– Axios Client
Yous can besides know way to upload an Excel/CSV file and store the content in MySQL database with the mail service:
– Leap Kicking: Upload/Import Excel file data into MySQL Database
– Bound Kick: Upload/Import CSV file data into MySQL Database
Happy Learning! See you lot again.
Further Reading
- Multipart Content-Type
- How to upload multiple files in Coffee Leap Boot
Deployment:
– Deploy Bound Kicking App on AWS – Elastic Beanstalk
– Docker Compose: Spring Boot and MySQL example
Source Code
You can find the consummate source code for this tutorial on Github.
Source: https://www.bezkoder.com/spring-boot-upload-file-database/
0 Response to "Upload Files to Database With Rest Api"
Post a Comment