diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/CategoryController.java b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/CategoryController.java index 7a63c69..6003748 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/CategoryController.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/CategoryController.java @@ -119,7 +119,7 @@ public ResponseEntity deleteCategory( @ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content) }) @PostMapping(path = "/{id}/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity uploadImage( + public ResponseEntity uploadImage( @Parameter( description = "Файл фотографии", required = true, @@ -127,7 +127,7 @@ public ResponseEntity uploadImage( ) @RequestParam("file") MultipartFile file, @PathVariable @Parameter(description = "id категории", example = "10") long id) { - categoryService.uploadImage(file, id); - return ResponseEntity.ok().build(); + Image image = categoryService.uploadImage(file, id); + return ResponseEntity.ok(image); } } diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/FacilityController.java b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/FacilityController.java index c7eec2e..8ae4251 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/FacilityController.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/FacilityController.java @@ -37,7 +37,7 @@ public class FacilityController { @ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content) }) @PostMapping(path = "/{id}/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity uploadImage( + public ResponseEntity uploadImage( @Parameter( description = "Файл фотографии", required = true, @@ -45,8 +45,8 @@ public ResponseEntity uploadImage( ) @RequestParam("file") MultipartFile file, @PathVariable @Parameter(description = "id категории", example = "10") long id) { - facilityService.uploadImage(file, id); - return ResponseEntity.ok().build(); + + return ResponseEntity.ok(facilityService.uploadImage(file, id)); } @Operation(summary = "Получение всех удобств", description = "Получение всех удобств") diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/ImageController.java b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/ImageController.java index 0c8dab2..1e84ae6 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/ImageController.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/ImageController.java @@ -10,24 +10,63 @@ import kattsyn.dev.rentplace.entities.Image; import kattsyn.dev.rentplace.enums.ImageType; import kattsyn.dev.rentplace.services.ImageService; -import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; 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.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("${api.path}/images") -@RequiredArgsConstructor +@Slf4j @Tag(name = "ImageController", description = "Для взаимодействия с фотографиями") public class ImageController { private final ImageService imageService; + private final Path rootLocation; + + public ImageController(ImageService imageService, @Value("${upload.path}") String uploadPath) { + this.imageService = imageService; + this.rootLocation = Paths.get(uploadPath).toAbsolutePath().normalize(); + } + + @GetMapping("/{entityType}/{entityId}/{filename:.+}") + public ResponseEntity getImage( + @PathVariable String entityType, + @PathVariable Long entityId, + @PathVariable String filename) { + + Path filePath = rootLocation.resolve(entityType) + .resolve(entityId.toString()) + .resolve(filename) + .normalize(); + + log.info(filePath.toString()); + + try { + Resource resource = new UrlResource(filePath.toUri()); + + if (resource.exists() || resource.isReadable()) { + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, Files.probeContentType(filePath)) + .body(resource); + } + return ResponseEntity.notFound().build(); + } catch (IOException e) { + return ResponseEntity.internalServerError().build(); + } + } @Operation( summary = "Загрузка фотографии", @@ -49,7 +88,7 @@ public ResponseEntity uploadImage( required = true, schema = @Schema( implementation = ImageType.class) - ) @RequestParam ImageType imageType) { + ) @RequestParam ImageType imageType) { //todo: delete method return ResponseEntity.ok(imageService.uploadImage(file, imageType)); } diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/PropertyController.java b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/PropertyController.java index 55ab06c..315aa3d 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/PropertyController.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/controllers/PropertyController.java @@ -10,10 +10,7 @@ import kattsyn.dev.rentplace.dtos.PropertyDTO; import kattsyn.dev.rentplace.entities.Image; import kattsyn.dev.rentplace.entities.Property; -import kattsyn.dev.rentplace.enums.ImageType; -import kattsyn.dev.rentplace.services.ImageService; import kattsyn.dev.rentplace.services.PropertyService; -import kattsyn.dev.rentplace.utils.PathResolver; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -30,7 +27,6 @@ public class PropertyController { private final PropertyService propertyService; - private final ImageService imageService; @PostMapping(value = "/{id}/images", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Operation( @@ -56,14 +52,6 @@ public ResponseEntity> uploadMultipleImages( return ResponseEntity.ok(savedImages); } - @PostMapping("/{id}/image") - public Image uploadPropertyImage( - @PathVariable Long id, - @RequestParam MultipartFile file) { - - String path = PathResolver.resolvePath(ImageType.PROPERTY, id); - return imageService.uploadImage(file, path); - } @Operation( summary = "Получение всех объявлений", diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/entities/Image.java b/rentplace/src/main/java/kattsyn/dev/rentplace/entities/Image.java index 1a855b6..d49d817 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/entities/Image.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/entities/Image.java @@ -19,6 +19,8 @@ public class Image { @Column(name = "file_name", length = 400) private String fileName; + @Column(name = "url", length = 1000) + private String url; @Column(name = "original_file_name") private String originalFileName; @Column(name = "content_type") diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/services/CategoryService.java b/rentplace/src/main/java/kattsyn/dev/rentplace/services/CategoryService.java index 392a18f..6214718 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/services/CategoryService.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/services/CategoryService.java @@ -2,6 +2,7 @@ import kattsyn.dev.rentplace.dtos.CategoryDTO; import kattsyn.dev.rentplace.entities.Category; +import kattsyn.dev.rentplace.entities.Image; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -14,6 +15,6 @@ public interface CategoryService { Category update(Long id, CategoryDTO categoryDTO); Category deleteById(Long id); - void uploadImage(MultipartFile file, long id); + Image uploadImage(MultipartFile file, long id); } diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/services/FacilityService.java b/rentplace/src/main/java/kattsyn/dev/rentplace/services/FacilityService.java index cd0c561..b781d97 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/services/FacilityService.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/services/FacilityService.java @@ -2,6 +2,7 @@ import kattsyn.dev.rentplace.dtos.FacilityDTO; import kattsyn.dev.rentplace.entities.Facility; +import kattsyn.dev.rentplace.entities.Image; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -14,5 +15,5 @@ public interface FacilityService { Facility update(Long id, FacilityDTO facilityDTO); Facility deleteById(Long id); - void uploadImage(MultipartFile file, long id); + Image uploadImage(MultipartFile file, long id); } diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/CategoryServiceImpl.java b/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/CategoryServiceImpl.java index c140ec9..3e9b88b 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/CategoryServiceImpl.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/CategoryServiceImpl.java @@ -61,7 +61,7 @@ public Category deleteById(Long id) { @Transactional @Override - public void uploadImage(MultipartFile file, long id) { + public Image uploadImage(MultipartFile file, long id) { Category category = findById(id); String path = PathResolver.resolvePath(ImageType.CATEGORY, id); @@ -71,5 +71,7 @@ public void uploadImage(MultipartFile file, long id) { Image image = imageService.uploadImage(file, path); category.setImage(image); categoryRepository.save(category); + + return image; } } diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/FacilityServiceImpl.java b/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/FacilityServiceImpl.java index 164c497..3763279 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/FacilityServiceImpl.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/FacilityServiceImpl.java @@ -61,7 +61,7 @@ public Facility deleteById(Long id) { @Transactional @Override - public void uploadImage(MultipartFile file, long id) { + public Image uploadImage(MultipartFile file, long id) { Facility facility = findById(id); String path = PathResolver.resolvePath(ImageType.FACILITY, id); @@ -71,5 +71,7 @@ public void uploadImage(MultipartFile file, long id) { Image image = imageService.uploadImage(file, path); facility.setImage(image); facilityRepository.save(facility); + + return image; } } diff --git a/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/ImageServiceImpl.java b/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/ImageServiceImpl.java index 30acc4d..eba342c 100644 --- a/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/ImageServiceImpl.java +++ b/rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/ImageServiceImpl.java @@ -7,6 +7,7 @@ import kattsyn.dev.rentplace.services.ImageService; import kattsyn.dev.rentplace.services.StorageService; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -18,6 +19,11 @@ public class ImageServiceImpl implements ImageService { private final ImageRepository imageRepository; private final StorageService storageService; + @Value("${app.base-url:http://localhost:8080}") + private String baseUrl; + @Value("${api.path}") + private String apiPath; + private void validateImage(MultipartFile file) { String contentType = file.getContentType(); if (file.isEmpty()) { @@ -42,10 +48,16 @@ public Image uploadImage(MultipartFile file) { image.setOriginalFileName(file.getOriginalFilename()); image.setContentType(file.getContentType()); image.setSize(file.getSize()); + image.setAdditionalPath(""); + image.setUrl(generateImageUrl("", filename)); return imageRepository.save(image); } + private String generateImageUrl(String relativePath, String fileName) { + return String.format("%s/%s/images%s%s", baseUrl, apiPath, relativePath, fileName); + } + @Override public Image uploadImage(MultipartFile file, ImageType type) { try { @@ -59,6 +71,7 @@ public Image uploadImage(MultipartFile file, ImageType type) { image.setContentType(file.getContentType()); image.setAdditionalPath(type.additionalPath); image.setSize(file.getSize()); + image.setUrl(generateImageUrl(type.additionalPath, filename)); return imageRepository.save(image); } catch (Exception e) { @@ -80,6 +93,7 @@ public Image uploadImage(MultipartFile file, String relativePath) { image.setContentType(file.getContentType()); image.setAdditionalPath(relativePath); image.setSize(file.getSize()); + image.setUrl(generateImageUrl(relativePath, filename)); return imageRepository.save(image); } catch (Exception e) { diff --git a/rentplace/src/main/resources/application.yml b/rentplace/src/main/resources/application.yml index fed95a5..b8804e4 100644 --- a/rentplace/src/main/resources/application.yml +++ b/rentplace/src/main/resources/application.yml @@ -14,9 +14,12 @@ spring: generate-ddl: true hibernate: ddl-auto: update + open-in-view: false api: path: api/v1 upload: - path: ./uploads + path: C:/Users/Kattsyn/TP-PROJECT/Backend/rentplace/uploads storage: - location: ./uploads/ \ No newline at end of file + location: ./uploads/ +app: + base-url: http://localhost:8080 \ No newline at end of file diff --git a/rentplace/src/main/resources/db/migration/V202503030016__images_init.sql b/rentplace/src/main/resources/db/migration/V202503030016__images_init.sql index 687fa8b..a212b41 100644 --- a/rentplace/src/main/resources/db/migration/V202503030016__images_init.sql +++ b/rentplace/src/main/resources/db/migration/V202503030016__images_init.sql @@ -1,6 +1,7 @@ CREATE TABLE images ( image_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, file_name VARCHAR(400) NOT NULL, + url VARCHAR(1000) NOT NULL, original_file_name VARCHAR(255) NOT NULL, additional_path VARCHAR(255) NOT NULL, size BIGINT NOT NULL,