Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Storing files in MySQL database
  • Loading branch information
Rajeev Kumar Singh committed Jul 5, 2018
commit 490d00922360c8737118630c352dd2d8cc52028d
11 changes: 11 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down
5 changes: 0 additions & 5 deletions src/main/java/com/example/filedemo/FileDemoApplication.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
package com.example.filedemo;

import com.example.filedemo.property.FileStorageProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@EnableConfigurationProperties({
FileStorageProperties.class
})
public class FileDemoApplication {

public static void main(String[] args) {
Expand Down
39 changes: 14 additions & 25 deletions src/main/java/com/example/filedemo/controller/FileController.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.example.filedemo.controller;

import com.example.filedemo.model.DBFile;
import com.example.filedemo.payload.UploadFileResponse;
import com.example.filedemo.service.FileStorageService;
import com.example.filedemo.service.DBFileStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
Expand All @@ -25,18 +27,18 @@ public class FileController {
private static final Logger logger = LoggerFactory.getLogger(FileController.class);

@Autowired
private FileStorageService fileStorageService;
private DBFileStorageService DBFileStorageService;

@PostMapping("/uploadFile")
public UploadFileResponse uploadFile(@RequestParam("file") MultipartFile file) {
String fileName = fileStorageService.storeFile(file);
DBFile dbFile = DBFileStorageService.storeFile(file);

String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(fileName)
.path(dbFile.getId())
.toUriString();

return new UploadFileResponse(fileName, fileDownloadUri,
return new UploadFileResponse(dbFile.getFileName(), fileDownloadUri,
file.getContentType(), file.getSize());
}

Expand All @@ -48,28 +50,15 @@ public List<UploadFileResponse> uploadMultipleFiles(@RequestParam("files") Multi
.collect(Collectors.toList());
}

@GetMapping("/downloadFile/{fileName:.+}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName, HttpServletRequest request) {
// Load file as Resource
Resource resource = fileStorageService.loadFileAsResource(fileName);

// Try to determine file's content type
String contentType = null;
try {
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException ex) {
logger.info("Could not determine file type.");
}

// Fallback to the default content type if type could not be determined
if(contentType == null) {
contentType = "application/octet-stream";
}
@GetMapping("/downloadFile/{fileId}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileId) {
// Load file from database
DBFile dbFile = DBFileStorageService.getFile(fileId);

return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
.contentType(MediaType.parseMediaType(dbFile.getFileType()))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + dbFile.getFileName() + "\"")
.body(new ByteArrayResource(dbFile.getData()));
}

}
63 changes: 63 additions & 0 deletions src/main/java/com/example/filedemo/model/DBFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.example.filedemo.model;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

@Entity
@Table(name = "files")
public class DBFile {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;

private String fileName;

private String fileType;

@Lob
private byte[] data;

public DBFile() {

}

public DBFile(String fileName, String fileType, byte[] data) {
this.fileName = fileName;
this.fileType = fileType;
this.data = data;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getFileName() {
return fileName;
}

public void setFileName(String fileName) {
this.fileName = fileName;
}

public String getFileType() {
return fileType;
}

public void setFileType(String fileType) {
this.fileType = fileType;
}

public byte[] getData() {
return data;
}

public void setData(byte[] data) {
this.data = data;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.filedemo.repository;

import com.example.filedemo.model.DBFile;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DBFileRepository extends JpaRepository<DBFile, String> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.filedemo.service;

import com.example.filedemo.exception.FileStorageException;
import com.example.filedemo.exception.MyFileNotFoundException;
import com.example.filedemo.model.DBFile;
import com.example.filedemo.repository.DBFileRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;

@Service
public class DBFileStorageService {

@Autowired
private DBFileRepository dbFileRepository;

public DBFile storeFile(MultipartFile file) {
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());

try {
// Check if the file's name contains invalid characters
if(fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}

DBFile dbFile = new DBFile(fileName, file.getContentType(), file.getBytes());

return dbFileRepository.save(dbFile);
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}

public DBFile getFile(String fileId) {
return dbFileRepository.findById(fileId)
.orElseThrow(() -> new MyFileNotFoundException("File not found with id " + fileId));
}
}
69 changes: 0 additions & 69 deletions src/main/java/com/example/filedemo/service/FileStorageService.java

This file was deleted.

17 changes: 15 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url= jdbc:mysql://localhost:3306/file_demo?useSSL=false
spring.datasource.username= root
spring.datasource.password= callicoder

## Hibernate Properties

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update

## Hibernate Logging
logging.level.org.hibernate.SQL= DEBUG


## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled=true
Expand All @@ -8,5 +23,3 @@ spring.servlet.multipart.max-file-size=50MB
# Max Request Size
spring.servlet.multipart.max-request-size=75MB

## File Storage Properties
file.upload-dir=./uploads