diff --git a/README.md b/README.md
index f8883f6..08f31a1 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@ This service is designed to integrate seamlessly with **Vault Web**, sharing its
- 🔹 **File Explorer-like API** for user files
- 🔹 **CRUD operations** on files and folders
- 🔹 **Secure access via JWT tokens** using Vault Web's master key
+ **Pagination and sorting for file listings
---
@@ -70,6 +71,27 @@ Then visit:
---
+Usage
+Pagination Example
+List files with pagination
+ GET /api/files/list?page=0&size=20&sort=name,asc
+Sample JSON response:
+{
+ "content": [
+ {
+ "name": "Doc1.txt",
+ "path": "/user/files/Doc1.txt",
+ "size": 12345,
+ "mimeType": "text/plain"
+ }
+ // ...
+ ],
+ "pageNumber": 0,
+ "totalElements": 52,
+ "totalPages": 3
+}
+
+
## Notes
* This service **depends on Vault Web** for database and authentication.
diff --git a/backend/pom.xml b/backend/pom.xml
index 7ddb3d8..987da6a 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -100,6 +100,13 @@
runtime
+
+ javax.persistence
+ javax.persistence-api
+ 2.2
+
+
+
org.springdoc
springdoc-openapi-starter-webmvc-ui
diff --git a/backend/src/main/java/cloudpage/controller/FileController.java b/backend/src/main/java/cloudpage/controller/FileController.java
index e92638e..a6b0301 100644
--- a/backend/src/main/java/cloudpage/controller/FileController.java
+++ b/backend/src/main/java/cloudpage/controller/FileController.java
@@ -1,5 +1,6 @@
package cloudpage.controller;
+import cloudpage.service.FileEntityService;
import cloudpage.service.FileService;
import cloudpage.service.FolderService;
import cloudpage.service.UserService;
@@ -10,6 +11,11 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
+import cloudpage.dto.FileDto;
+import cloudpage.model.File;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Pageable;
import java.io.IOException;
import java.nio.file.Files;
@@ -24,6 +30,8 @@ public class FileController {
private final FileService fileService;
private final UserService userService;
private final FolderService folderService;
+ private final FileEntityService fileEntityService;
+;
@PostMapping("/upload")
public void uploadFile(@RequestParam String folderPath, @RequestParam MultipartFile file) throws IOException {
@@ -88,4 +96,23 @@ public ResponseEntity viewFile(@RequestParam String path) throws IOExc
.header(HttpHeaders.CONTENT_TYPE, mimeType)
.body(resource);
}
+ @GetMapping("/list")
+public ResponseEntity> listFilesWithPagination(
+ @RequestParam(defaultValue = "0") int page,
+ @RequestParam(defaultValue = "10") int size,
+ @RequestParam(defaultValue = "name,asc") String[] sort
+) {
+ // Example sort param: ["name", "asc"]
+ Sort.Direction direction = sort[1].equalsIgnoreCase("desc") ? Sort.Direction.DESC : Sort.Direction.ASC;
+ Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sort[0]));
+ var filePage = fileEntityService.getAllFiles(pageable);
+
+ FileDto response = new FileDto<>(
+ filePage.getContent(),
+ filePage.getNumber(),
+ filePage.getTotalElements(),
+ filePage.getTotalPages()
+ );
+ return ResponseEntity.ok(response);
+}
}
\ No newline at end of file
diff --git a/backend/src/main/java/cloudpage/dto/FileDto.java b/backend/src/main/java/cloudpage/dto/FileDto.java
index cc4c353..8b6c495 100644
--- a/backend/src/main/java/cloudpage/dto/FileDto.java
+++ b/backend/src/main/java/cloudpage/dto/FileDto.java
@@ -3,13 +3,98 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
+import java.util.List;
@Getter
@Setter
@AllArgsConstructor
-public class FileDto {
+public class FileDto {
private String name;
private String path;
private long size;
private String mimeType;
+ private List content;
+ private int pageNumber;
+ private long totalElements;
+ private int totalPages;
+
+ public FileDto(List content, int pageNumber, long totalElements, int totalPages) {
+ this.content = content;
+ this.pageNumber = pageNumber;
+ this.totalElements = totalElements;
+ this.totalPages = totalPages;
+ }
+ public FileDto() {
+ }
+ public FileDto(String name, String path, long size, String mimeType) {
+ this.name = name;
+ this.path = path;
+ this.size = size;
+ this.mimeType = mimeType;
+}
+
+ public String getName() {
+ return name;
+}
+
+public void setName(String name) {
+ this.name = name;
+}
+
+public String getPath() {
+ return path;
+}
+
+public void setPath(String path) {
+ this.path = path;
+}
+
+public long getSize() {
+ return size;
+}
+
+public void setSize(long size) {
+ this.size = size;
+}
+
+public String getMimeType() {
+ return mimeType;
+}
+
+public void setMimeType(String mimeType) {
+ this.mimeType = mimeType;
+}
+
+public List getContent() {
+ return content;
+}
+
+public void setContent(List content) {
+ this.content = content;
+}
+
+public int getPageNumber() {
+ return pageNumber;
+}
+
+public void setPageNumber(int pageNumber) {
+ this.pageNumber = pageNumber;
+}
+
+public long getTotalElements() {
+ return totalElements;
+}
+
+public void setTotalElements(long totalElements) {
+ this.totalElements = totalElements;
+}
+
+public int getTotalPages() {
+ return totalPages;
+}
+
+public void setTotalPages(int totalPages) {
+ this.totalPages = totalPages;
+}
+
}
diff --git a/backend/src/main/java/cloudpage/model/File.java b/backend/src/main/java/cloudpage/model/File.java
new file mode 100644
index 0000000..dc39ee0
--- /dev/null
+++ b/backend/src/main/java/cloudpage/model/File.java
@@ -0,0 +1,50 @@
+package cloudpage.model;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+
+@Entity
+@Table(name = "files")
+public class File {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String name;
+
+ private String path;
+
+ private Long size;
+
+ private String fileType;
+
+ // Constructors
+ public File() {}
+
+ public File(String name, String path, Long size, String fileType) {
+ this.name = name;
+ this.path = path;
+ this.size = size;
+ this.fileType = fileType;
+ }
+
+ // Getters and setters
+ public Long getId() { return id; }
+ public void setId(Long id) { this.id = id; }
+
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name; }
+
+ public String getPath() { return path; }
+ public void setPath(String path) { this.path = path; }
+
+ public Long getSize() { return size; }
+ public void setSize(Long size) { this.size = size; }
+
+ public String getFileType() { return fileType; }
+ public void setFileType(String fileType) { this.fileType = fileType; }
+}
diff --git a/backend/src/main/java/cloudpage/repository/FileRepository.java b/backend/src/main/java/cloudpage/repository/FileRepository.java
new file mode 100644
index 0000000..3c8c0a9
--- /dev/null
+++ b/backend/src/main/java/cloudpage/repository/FileRepository.java
@@ -0,0 +1,11 @@
+package cloudpage.repository;
+
+import cloudpage.model.File;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface FileRepository extends PagingAndSortingRepository {
+ // Define custom queries here (if needed)
+}
+
diff --git a/backend/src/main/java/cloudpage/service/FileEntityService.java b/backend/src/main/java/cloudpage/service/FileEntityService.java
new file mode 100644
index 0000000..6c7fa3a
--- /dev/null
+++ b/backend/src/main/java/cloudpage/service/FileEntityService.java
@@ -0,0 +1,9 @@
+package cloudpage.service;
+
+import cloudpage.model.File;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+public interface FileEntityService {
+ Page getAllFiles(Pageable pageable);
+}
diff --git a/backend/src/main/java/cloudpage/service/FileService.java b/backend/src/main/java/cloudpage/service/FileService.java
index 8e5d110..922fc9e 100644
--- a/backend/src/main/java/cloudpage/service/FileService.java
+++ b/backend/src/main/java/cloudpage/service/FileService.java
@@ -8,6 +8,9 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
+import cloudpage.model.File;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
@Service
public class FileService {
@@ -54,4 +57,5 @@ private void validatePath(String rootPath, Path path) {
throw new IllegalArgumentException("Access outside the user's root folder is forbidden: " + path);
}
}
+
}
\ No newline at end of file
diff --git a/backend/src/main/java/cloudpage/service/impl/FileEntityServiceImpl.java b/backend/src/main/java/cloudpage/service/impl/FileEntityServiceImpl.java
new file mode 100644
index 0000000..f592b75
--- /dev/null
+++ b/backend/src/main/java/cloudpage/service/impl/FileEntityServiceImpl.java
@@ -0,0 +1,21 @@
+package cloudpage.service.impl;
+
+import cloudpage.model.File;
+import cloudpage.repository.FileRepository;
+import cloudpage.service.FileEntityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FileEntityServiceImpl implements FileEntityService {
+
+ @Autowired
+ private FileRepository fileRepository;
+
+ @Override
+ public Page getAllFiles(Pageable pageable) {
+ return fileRepository.findAll(pageable);
+ }
+}