In the tutorial, we will show you how to create a SpringBoot project to download/upload MultipartFile to PostgreSQL using Spring Hibernate JPA, JQuery Ajax, Bootstrap 4.
Related posts:
– Spring Hibernate JPA – Upload/Download File/Image to PostgreSQL with @Lob
Contents
Technologies
- Java 8
- Maven 3.6.1
- Spring Tool Suite: Version 3.9.4.RELEASE
- Spring Boot: 2.0.2.RELEASE
- JQuery Ajax
- Bootstrap 4
Goal
We create a SpringBoot project as below:
-> Upload/Download Form:
-> PostgreSQL’s records:
Practice
We create a SpringBoot project with below dependencies:
- spring-boot-starter-thymeleaf
- spring-boot-starter-web
- spring-boot-starter-data-jpa
- postgresql
-> Details:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> |
FrontEnd
Upload Multipart-Form
<!DOCTYPE html> <html lang="en"> <head> <title>Upload MultipartFile</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <script src="/js/postrequest.js"></script> <script src="/js/getrequest.js"></script> </head> <body> <div class="container h-100"> <div class="row h-100 justify-content-center align-items-center"> <div class="col-sm-6"> <h3>Upload MultipartFile to PostgreSQL</h3> <form method="POST" enctype="multipart/form-data" id="fileUploadForm"> <div class="form-group"> <label class="control-label" for="uploadfile">Upload File:</label> <input type="file" class="form-control" id="uploadfile" placeholder="Upload File" name="uploadfile"></input> </div> <button type="submit" class="btn btn-default" id="btnSubmit">Upload</button> <button type="button" class="btn btn-default" id="btnGetFiles">Files</button> </form> <hr/> <div id="listFiles"> </div> </div> </div> </div> </body> </html> |
Ajax Post/Get MultipartFile
– JQuery Ajax to Post MultipartFile is implemented in \src\main\resources\static\js\postrequest.js file:
$(document).ready( () => { $("#btnSubmit").click((event) => { //stop submit the form, we will post it manually. event.preventDefault(); doAjax(); }); }); function doAjax() { // Get form var form = $('#fileUploadForm')[0]; var data = new FormData(form); $.ajax({ type: "POST", enctype: 'multipart/form-data', url: "/api/file/upload", data: data, processData: false, //prevent jQuery from automatically transforming the data into a query string contentType: false, cache: false, success: (data) => { $("#listFiles").text(data); }, error: (e) => { $("#listFiles").text(e.responseText); } }); } |
– JQuery Ajax to Retrieve/Download MultipartFile is implemented in \src\main\resources\static\js\getrequest.js file:
$( document ).ready( () => { var url = window.location; // GET REQUEST $("#btnGetFiles").click( (event) => { event.preventDefault(); ajaxGet(); }); // DO GET function ajaxGet(){ $.ajax({ type : "GET", dataType: "json", url : "/api/file/all", success: (data) => { //clear old data $("#listFiles").html(""); /* render list of files */ $("#listFiles").append('<ul>'); $.each(data, (index, file) => { $("#listFiles").append('<li><a href=' + url + 'api/file/' + file.id +'>' + file.name + '</a></li>'); }); $("#listFiles").append('</ul>'); }, error : (err) => { $("#listFiles").html(err.responseText); } }); } }) |
BackEnd
Data Model
– Create a View with @JsonView
in View.java file:
package com.javasampleapproach.multipartfile.model; public class View { public interface FileInfo {} } |
– Create FileModel.java file:
package com.javasampleapproach.multipartfile.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonView; @Entity @Table(name="file_model") public class FileModel { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") @JsonView(View.FileInfo.class) private Long id; @Column(name = "name") @JsonView(View.FileInfo.class) private String name; @Column(name = "mimetype") private String mimetype; @Lob @Column(name="pic") private byte[] pic; public FileModel(){} public FileModel(String name, String mimetype, byte[] pic){ this.name = name; this.mimetype = mimetype; this.pic = pic; } public Long getId(){ return this.id; } public void setId(Long id){ this.id = id; } public String getName(){ return this.name; } public void setName(String name){ this.name = name; } public String getMimetype(){ return this.mimetype; } public void setMimetype(String mimetype){ this.mimetype = mimetype; } public byte[] getPic(){ return this.pic; } public void setPic(byte[] pic){ this.pic = pic; } } |
JPA Repository
Implement JPA repository in FileRepository file:
package com.javasampleapproach.multipartfile.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.transaction.annotation.Transactional; import com.javasampleapproach.multipartfile.model.FileModel; @Transactional public interface FileRepository extends JpaRepository<FileModel, Long>{ public FileModel findByName(String name); } |
– Configure @EnableTransactionManagement
in main class SpringBootUploadMultipartFile2PostgreSqlApplication:
package com.javasampleapproach.multipartfile; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication @EnableTransactionManagement public class SpringBootUploadMultipartFile2PostgreSqlApplication { public static void main(String[] args) { SpringApplication.run(SpringBootUploadMultipartFile2PostgreSqlApplication.class, args); } } |
Index Controller
Create IndexController.java file to serve uploadfile.html form:
package com.javasampleapproach.multipartfile.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class IndexController { @GetMapping("/") public String index() { return "uploadfile"; } } |
Upload/Download RestAPIs
– Implement upload-file RestAPI in UploadFileController.java file:
package com.javasampleapproach.multipartfile.controller.rest; import org.springframework.beans.factory.annotation.Autowired; 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.javasampleapproach.multipartfile.model.FileModel; import com.javasampleapproach.multipartfile.repository.FileRepository; @RestController public class UploadFileController { @Autowired FileRepository fileRepository; /* * MultipartFile Upload */ @PostMapping("/api/file/upload") public String uploadMultipartFile(@RequestParam("uploadfile") MultipartFile file) { try { // save file to PostgreSQL FileModel filemode = new FileModel(file.getOriginalFilename(), file.getContentType(), file.getBytes()); fileRepository.save(filemode); return "File uploaded successfully! -> filename = " + file.getOriginalFilename(); } catch ( Exception e) { return "FAIL! Maybe You had uploaded the file before or the file's size > 500KB"; } } } |
– Implement download/retrieve files RestAPI
s in DownloadFileController.java file:
package com.javasampleapproach.multipartfile.controller.rest; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.annotation.JsonView; import com.javasampleapproach.multipartfile.model.FileModel; import com.javasampleapproach.multipartfile.model.View; import com.javasampleapproach.multipartfile.repository.FileRepository; @RestController public class DownloadFileController { @Autowired FileRepository fileRepository; /* * List All Files */ @JsonView(View.FileInfo.class) @GetMapping("/api/file/all") public List<FileModel> getListFiles() { return fileRepository.findAll(); } /* * Download Files */ @GetMapping("/api/file/{id}") public ResponseEntity<byte[]> getFile(@PathVariable Long id) { Optional<FileModel> fileOptional = fileRepository.findById(id); if(fileOptional.isPresent()) { FileModel file = fileOptional.get(); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"") .body(file.getPic()); } return ResponseEntity.status(404).body(null); } } |
PostgreSQL Connection
– Add setting in application.properties file:
spring.datasource.url=jdbc:postgresql://localhost/test spring.datasource.username=postgres spring.datasource.password=123 spring.jpa.generate-ddl=true spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false spring.jpa.hibernate.ddl-auto=create-drop |
Run & Check Results
Run the SpringBoot project, then makes upload/download requests ->
Upload Files
-> Browser Network logs:
-> PostgreSQL records:
Retrieve Files
-> Browser Network logs:
Download Files
-> Browser Network logs: