I am trying to display some documents on a page. I have saved them in the database but I am not sure how to go on displaying them on the website and make them downloadable. The files have the format (pdf, doc, ppt). If anyone could suggest something, I'd be grateful.
This is the File Entity:
@Entity
@Table(name = "chapter_files")
public class File {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "file_id")
private Long id;
@Column(name = "file_name")
private String fileName;
@Column(name = "file")
@Lob
private byte[] file;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="chapter_id")
private Chapter chapter;
}
This is the MySQL table create query:
CREATE TABLE `chapter_files` (
`file_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`file_name` VARCHAR(50) NOT NULL,
`file` LONGTEXT NOT NULL,
`chapter_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`file_id`),
INDEX `FKChapter` (`chapter_id`),
CONSTRAINT `FKChapter` FOREIGN KEY (`chapter_id`) REFERENCES `chapters` (`chapter_id`)
)
This is the Service class method to save the files in the database:
public File saveFiles(MultipartFile file, Chapter chapter) {
File doc = new File();
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
doc.setFileName(fileName);
try {
doc.setFile(file.getBytes());
doc.setChapter(chapter);
} catch (IOException e) {
e.printStackTrace();
}
return fileRepository.save(doc);
}
I am not sure how I should display the files on the page and make them downloadable. If you have any suggestions or any articles I could read, I'd gladly follow.
This should work for your regular Spring MVC app:
The steps are:
import org.springframework.stereotype.Controller;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
@Controller
@RequestMapping("/download")
public class DownloadController {
@GetMapping("/file/{id}")
public void downloadFile(@PathVariable Long fileId, HttpServletResponse resp) throws IOException {
File dbFile = fileRepository.readFile(fileId);
byte[] byteArray = dbFile.getFile(); // read the byteArray
resp.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM.getType());
resp.setHeader("Content-Disposition", "attachment; filename=" + dbFile.fileName());
resp.setContentLength(byteArray.length);
OutputStream os = resp.getOutputStream();
try {
os.write(byteArray, 0, byteArray.length);
} finally {
os.close();
}
}
}
In your Thymeleaf template, you can use the following to create a link to download file:
<a th:href="@{/download/file/{id}(id=${file.id})}">
<span th:text="${file.fileName}">Download</span>
</a>
If you want to read the file from disk and download, you might need to do sth similar to this: https://github.com/gtiwari333/spring-boot-web-application-seed/blob/master/main-app/src/main/java/gt/app/web/mvc/DownloadController.java
Also, if you are using SPA eg: AngularJS/Angular etc client then you might need to follow slightly different approach. See here for an example.
http://ganeshtiwaridotcomdotnp.blogspot.com/2017/01/angularjs-download-file-from-server.html