-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add media service * fix some error and config download * fix sonar
- Loading branch information
Showing
12 changed files
with
445 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
src/main/java/com/fjb/sunrise/controllers/MediaController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.fjb.sunrise.controllers; | ||
|
||
import com.fjb.sunrise.dtos.responses.MediaResponse; | ||
import com.fjb.sunrise.exceptions.BadRequestException; | ||
import com.fjb.sunrise.models.Media; | ||
import com.fjb.sunrise.services.MediaService; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.core.io.ByteArrayResource; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import org.springframework.web.servlet.ModelAndView; | ||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder; | ||
|
||
@Controller | ||
@RequiredArgsConstructor | ||
@RequestMapping("/medias") | ||
public class MediaController { | ||
|
||
private final MediaService mediaService; | ||
|
||
@GetMapping | ||
public ModelAndView index() { | ||
return new ModelAndView("media/index"); | ||
} | ||
|
||
@PostMapping("/upload") | ||
public ModelAndView uploadFile(@RequestParam("file") MultipartFile file) { | ||
try { | ||
mediaService.store(file); | ||
} catch (Exception ignored) { | ||
throw new BadRequestException("Error when upload file"); | ||
} | ||
return new ModelAndView("redirect:/medias"); | ||
} | ||
|
||
@GetMapping("/files") | ||
public ModelAndView getListFiles() { | ||
List<MediaResponse> files = mediaService.getAllMedias().map(dbFile -> { | ||
String fileDownloadUri = ServletUriComponentsBuilder | ||
.fromCurrentContextPath() | ||
.path("/medias/files/") | ||
.path(dbFile.getFileCode()) | ||
.toUriString(); | ||
|
||
return new MediaResponse( | ||
dbFile.getName(), | ||
dbFile.getFileCode(), | ||
fileDownloadUri, | ||
dbFile.getType(), | ||
dbFile.getData().length); | ||
}).toList(); | ||
|
||
ModelAndView modelAndView = new ModelAndView("media/index"); | ||
|
||
modelAndView.addObject("files", files); | ||
return modelAndView; | ||
} | ||
|
||
@GetMapping("/files/{fileCode}") | ||
public ResponseEntity<byte[]> getFile(@PathVariable String fileCode) { | ||
Media fileDB = mediaService.getMedia(fileCode); | ||
|
||
return ResponseEntity.ok() | ||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileDB.getName() + "\"") | ||
.body(fileDB.getData()); | ||
} | ||
|
||
@GetMapping("/media/{fileCode}") | ||
public ResponseEntity<ByteArrayResource> getMedia(@PathVariable String fileCode) { | ||
Media media = mediaService.getMedia(fileCode); | ||
if (media == null) { | ||
return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); | ||
} | ||
|
||
ByteArrayResource resource = new ByteArrayResource(media.getData()); | ||
return ResponseEntity.ok() | ||
.header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + media.getName() + "\"") | ||
.contentType(MediaType.parseMediaType(media.getType())) | ||
.contentLength(media.getData().length) | ||
.body(resource); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/fjb/sunrise/dtos/responses/MediaResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.fjb.sunrise.dtos.responses; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
@AllArgsConstructor | ||
public class MediaResponse { | ||
private String name; | ||
private String fileCode; | ||
private String url; | ||
private String type; | ||
private long size; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.fjb.sunrise.models; | ||
|
||
import jakarta.persistence.Basic; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Lob; | ||
import jakarta.persistence.Table; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
@Entity | ||
@Getter | ||
@Setter | ||
@Builder | ||
@Table(name = "medias") | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public class Media { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
private String name; | ||
|
||
private String type; | ||
|
||
@Lob | ||
@Basic(fetch = FetchType.LAZY) | ||
private byte[] data; | ||
|
||
private String fileCode; | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/fjb/sunrise/repositories/MediaRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.fjb.sunrise.repositories; | ||
|
||
import com.fjb.sunrise.models.Media; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface MediaRepository extends JpaRepository<Media, Long> { | ||
Media findByFileCode(String fileCode); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.fjb.sunrise.services; | ||
|
||
import com.fjb.sunrise.exceptions.BadRequestException; | ||
import com.fjb.sunrise.models.Media; | ||
import com.fjb.sunrise.repositories.MediaRepository; | ||
import java.io.IOException; | ||
import java.util.UUID; | ||
import java.util.stream.Stream; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.util.StringUtils; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class MediaService { | ||
|
||
private final MediaRepository mediaRepository; | ||
|
||
public Media store(MultipartFile file) throws IOException { | ||
if (file == null || file.getOriginalFilename() == null) { | ||
throw new BadRequestException("File is null"); | ||
} | ||
String fileName = StringUtils.cleanPath(file.getOriginalFilename()); | ||
String fileCode = UUID.randomUUID().toString(); | ||
Media media = Media.builder() | ||
.name(fileName) | ||
.type(file.getContentType()) | ||
.data(file.getBytes()) | ||
.fileCode(fileCode) | ||
.build(); | ||
|
||
return mediaRepository.save(media); | ||
} | ||
|
||
@Transactional | ||
public Media getMedia(String fileCode) { | ||
return mediaRepository.findByFileCode(fileCode); | ||
} | ||
|
||
public Stream<Media> getAllMedias() { | ||
return mediaRepository.findAll().stream(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" | ||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>Media</title> | ||
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" type="text/css"> | ||
<script th:src="@{/js/bootstrap.bundle.min.js}" type="text/javascript"></script> | ||
|
||
<!-- Custom fonts for this template--> | ||
<link th:href="@{/vendor/fontawesome-free/css/all.min.css}" rel="stylesheet" type="text/css"> | ||
<link | ||
href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" | ||
rel="stylesheet"> | ||
|
||
<!-- Custom styles for this template--> | ||
<link th:href="@{/css/sb-admin-2.min.css}" rel="stylesheet" type="text/css"> | ||
<!-- Custom styles for this page --> | ||
<link th:href="@{/vendor/datatables/dataTables.bootstrap4.min.css}" rel="stylesheet" type="text/css"> | ||
<script th:src="@{/js/bootstrap.bundle.min.js}" type="text/javascript"></script> | ||
</head> | ||
<body id="page-top"> | ||
|
||
<!-- Page Wrapper --> | ||
<div id="wrapper"> | ||
|
||
<!-- Sidebar from fragment --> | ||
<div th:replace="~{tab_bar :: tab-bar}"></div> | ||
|
||
<!-- Content Wrapper --> | ||
<div id="content-wrapper" class="d-flex flex-column"> | ||
|
||
<!-- Main Content --> | ||
<div id="content"> | ||
|
||
<!-- Header from fragment --> | ||
<div th:replace="~{header :: header}"></div> | ||
|
||
<div class="container-fluid"> | ||
|
||
<div class="container mt-5"> | ||
<h2>Upload Media Files</h2> | ||
|
||
<form th:action="@{/medias/upload}" method="post" enctype="multipart/form-data"> | ||
<div class="form-group"> | ||
<label for="file">Choose file</label> | ||
<input type="file" id="file" name="file" class="form-control" required> | ||
</div> | ||
<button type="submit" class="btn btn-primary">Upload</button> | ||
</form> | ||
|
||
<hr> | ||
|
||
<div th:if="${files != null and #lists.size(files) > 0}"> | ||
<h3>Uploaded Files</h3> | ||
<table class="table"> | ||
<thead> | ||
<tr> | ||
<th>Name</th> | ||
<th>File Code</th> | ||
<th>Type</th> | ||
<th>Size (bytes)</th> | ||
<th>Download</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr th:each="file : ${files}"> | ||
<td th:text="${file.name}"></td> | ||
<td th:text="${file.fileCode}"></td> | ||
<td th:text="${file.type}"></td> | ||
<td th:text="${file.size}"></td> | ||
<td> | ||
<a th:href="${file.url}" class="btn btn-success btn-sm">Download</a> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
|
||
</div> | ||
|
||
</div> | ||
|
||
</div> | ||
|
||
<!-- Bootstrap core JavaScript--> | ||
<script th:src="@{/vendor/jquery/jquery.min.js}" type="application/javascript"></script> | ||
<script th:src="@{/vendor/bootstrap/js/bootstrap.bundle.min.js}" type="application/javascript"></script> | ||
|
||
<!-- Core plugin JavaScript--> | ||
<script th:src="@{/vendor/jquery-easing/jquery.easing.min.js}" type="application/javascript"></script> | ||
|
||
<!-- Custom scripts for all pages--> | ||
<script th:src="@{/js/sb-admin-2.min.js}" type="application/javascript"></script> | ||
|
||
<!-- Page level plugins --> | ||
<script th:src="@{/vendor/datatables/jquery.dataTables.min.js}" type="application/javascript"></script> | ||
<script th:src="@{/vendor/datatables/dataTables.bootstrap4.min.js}" type="application/javascript"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.