From 15bbc3f95d7965d05e7cb108377d48669585344f Mon Sep 17 00:00:00 2001 From: mehmet Date: Wed, 19 Aug 2026 11:04:06 +0300 Subject: [PATCH] first issue --- .gitignore | 50 ++++--- apiPdfUploader/pom.xml | 82 ++++++++++++ apiPdfUploader/schema-mssql.sql | 26 ++++ .../pdfservice/PdfServiceApplication.java | 15 +++ .../config/FileStorageProperties.java | 22 +++ .../example/pdfservice/config/WebConfig.java | 21 +++ .../pdfservice/controller/FileController.java | 76 +++++++++++ .../example/pdfservice/dto/FileResponse.java | 60 +++++++++ .../pdfservice/entity/FileDocument.java | 108 +++++++++++++++ .../exception/FileNotFoundException.java | 12 ++ .../exception/GlobalExceptionHandler.java | 46 +++++++ .../repository/FileDocumentRepository.java | 7 + .../service/FileStorageService.java | 125 ++++++++++++++++++ .../src/main/resources/application.properties | 24 ++++ ...-cb08298fe238-01 Ekler KAAN P1S2 ExPS .pdf | Bin 0 -> 29742866 bytes ...a62-9e3a-8be29452f7f3-ExPS_CMP_REV 7.0.pdf | Bin 0 -> 2447255 bytes ...9f3-6f1ad9930761-2420_260805113124_001.pdf | Bin 0 -> 2138626 bytes webPdfUploader/package.json | 34 +++++ webPdfUploader/public/index.html | 12 ++ webPdfUploader/src/App.css | 116 ++++++++++++++++ webPdfUploader/src/App.js | 52 ++++++++ webPdfUploader/src/api/fileApi.js | 32 +++++ webPdfUploader/src/components/FileList.js | 54 ++++++++ webPdfUploader/src/components/FilePreview.js | 31 +++++ webPdfUploader/src/components/FileUpload.js | 60 +++++++++ webPdfUploader/src/index.js | 6 + 26 files changed, 1056 insertions(+), 15 deletions(-) create mode 100644 apiPdfUploader/pom.xml create mode 100644 apiPdfUploader/schema-mssql.sql create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/PdfServiceApplication.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/config/FileStorageProperties.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/config/WebConfig.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/controller/FileController.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/dto/FileResponse.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/entity/FileDocument.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/exception/FileNotFoundException.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/exception/GlobalExceptionHandler.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/repository/FileDocumentRepository.java create mode 100644 apiPdfUploader/src/main/java/com/example/pdfservice/service/FileStorageService.java create mode 100644 apiPdfUploader/src/main/resources/application.properties create mode 100644 apiPdfUploader/storage/pdf-files/40cedaf7-9ee1-4528-b909-cb08298fe238-01 Ekler KAAN P1S2 ExPS .pdf create mode 100644 apiPdfUploader/storage/pdf-files/5cd7fae0-ab4d-4a62-9e3a-8be29452f7f3-ExPS_CMP_REV 7.0.pdf create mode 100644 apiPdfUploader/storage/pdf-files/99344888-76e0-4f40-89f3-6f1ad9930761-2420_260805113124_001.pdf create mode 100644 webPdfUploader/package.json create mode 100644 webPdfUploader/public/index.html create mode 100644 webPdfUploader/src/App.css create mode 100644 webPdfUploader/src/App.js create mode 100644 webPdfUploader/src/api/fileApi.js create mode 100644 webPdfUploader/src/components/FileList.js create mode 100644 webPdfUploader/src/components/FilePreview.js create mode 100644 webPdfUploader/src/components/FileUpload.js create mode 100644 webPdfUploader/src/index.js diff --git a/.gitignore b/.gitignore index 9154f4c..2ff1fa2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,9 @@ -# ---> Java -# Compiled class file +### Java +apiPdfUploader/target/ + +# files *.class - -# Log file *.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # *.jar *.war *.nar @@ -20,7 +12,35 @@ *.tar.gz *.rar -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -replay_pid* +#Eclipse Specific +.metadata/ +bin/ +tmp/ +*.tmp +*.bak +*.swp +local.properties +.settings/ +.loadpath +.recommenders +.project +.classpath +.factorypath + +### NodeJS +webPdfUploader/node_modules/ +webPdfUploader/build/ +webPdfUploader/package-lock.json + +# VSCode +.vscode/ + + +### OS Specific +.DS_Store +Thumbs.db + + +### Other +fullstackPdfUploader/apiPdfUploader/storage diff --git a/apiPdfUploader/pom.xml b/apiPdfUploader/pom.xml new file mode 100644 index 0000000..cbfdab6 --- /dev/null +++ b/apiPdfUploader/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.4 + + + + com.example + apiPdfUploader + 1.0.0 + apiPdfFileManager + Sample Spring Boot REST API for storing/serving PDF files with MSSQL metadata + + + 21 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-validation + + + + + com.microsoft.sqlserver + mssql-jdbc + runtime + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/apiPdfUploader/schema-mssql.sql b/apiPdfUploader/schema-mssql.sql new file mode 100644 index 0000000..8ff8824 --- /dev/null +++ b/apiPdfUploader/schema-mssql.sql @@ -0,0 +1,26 @@ +-- Reference schema for MS SQL Server. +-- Not required to run manually if spring.jpa.hibernate.ddl-auto=update is left enabled, +-- but useful for real deployments where DDL is managed separately. + +IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'pdf_file_db') +BEGIN + CREATE DATABASE pdf_file_db; +END +GO + +USE pdf_file_db; +GO + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'file_document') +BEGIN + CREATE TABLE file_document ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + original_file_name NVARCHAR(255) NOT NULL, + stored_file_name NVARCHAR(255) NOT NULL, + file_path NVARCHAR(1000) NOT NULL, + content_type NVARCHAR(100) NULL, + file_size BIGINT NOT NULL DEFAULT 0, + upload_date DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME() + ); +END +GO diff --git a/apiPdfUploader/src/main/java/com/example/pdfservice/PdfServiceApplication.java b/apiPdfUploader/src/main/java/com/example/pdfservice/PdfServiceApplication.java new file mode 100644 index 0000000..772909e --- /dev/null +++ b/apiPdfUploader/src/main/java/com/example/pdfservice/PdfServiceApplication.java @@ -0,0 +1,15 @@ +package com.example.pdfservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; + +@SpringBootApplication +@ConfigurationPropertiesScan +public class PdfServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(PdfServiceApplication.class, args); + } + +} diff --git a/apiPdfUploader/src/main/java/com/example/pdfservice/config/FileStorageProperties.java b/apiPdfUploader/src/main/java/com/example/pdfservice/config/FileStorageProperties.java new file mode 100644 index 0000000..668a1af --- /dev/null +++ b/apiPdfUploader/src/main/java/com/example/pdfservice/config/FileStorageProperties.java @@ -0,0 +1,22 @@ +package com.example.pdfservice.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Reads "app.file.storage-dir" from application.properties. + * This is the ROOT directory on disk where uploaded PDFs are physically kept. + * The full path of each individual file is what gets persisted in the DB. + */ +@ConfigurationProperties(prefix = "app.file") +public class FileStorageProperties { + + private String storageDir; + + public String getStorageDir() { + return storageDir; + } + + public void setStorageDir(String storageDir) { + this.storageDir = storageDir; + } +} diff --git a/apiPdfUploader/src/main/java/com/example/pdfservice/config/WebConfig.java b/apiPdfUploader/src/main/java/com/example/pdfservice/config/WebConfig.java new file mode 100644 index 0000000..7af319c --- /dev/null +++ b/apiPdfUploader/src/main/java/com/example/pdfservice/config/WebConfig.java @@ -0,0 +1,21 @@ +package com.example.pdfservice.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * Allows the React dev server (http://localhost:3000) to call this API + * during local development. Tighten this for production deployments. + */ +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/api/**") + .allowedOrigins("http://localhost:3000") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("*"); + } +} diff --git a/apiPdfUploader/src/main/java/com/example/pdfservice/controller/FileController.java b/apiPdfUploader/src/main/java/com/example/pdfservice/controller/FileController.java new file mode 100644 index 0000000..3b06562 --- /dev/null +++ b/apiPdfUploader/src/main/java/com/example/pdfservice/controller/FileController.java @@ -0,0 +1,76 @@ +package com.example.pdfservice.controller; + +import com.example.pdfservice.dto.FileResponse; +import com.example.pdfservice.entity.FileDocument; +import com.example.pdfservice.service.FileStorageService; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +@RestController +@RequestMapping("/api/files") +public class FileController { + + private final FileStorageService fileStorageService; + + public FileController(FileStorageService fileStorageService) { + this.fileStorageService = fileStorageService; + } + + /** 6. List all files */ + @GetMapping + public ResponseEntity> listFiles() { + return ResponseEntity.ok(fileStorageService.listAll()); + } + + /** 7. Upload a new PDF file (multipart/form-data, field name "file") */ + @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) { + FileResponse response = fileStorageService.store(file); + return ResponseEntity.ok(response); + } + + /** 7. Download a file as an attachment */ + @GetMapping("/{id}/download") + public ResponseEntity downloadFile(@PathVariable Long id) { + FileDocument metadata = fileStorageService.getMetadata(id); + Resource resource = fileStorageService.loadAsResource(id); + + String encodedName = URLEncoder.encode(metadata.getOriginalFileName(), StandardCharsets.UTF_8); + + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_PDF) + .header(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=\"" + metadata.getOriginalFileName() + "\"; filename*=UTF-8''" + encodedName) + .body(resource); + } + + /** 8. Preview a file inline in the browser (e.g. inside an