WIP for images

This commit is contained in:
2025-04-24 07:34:53 +02:00
parent a3d3a01d3a
commit 6b5dded7f8
6 changed files with 119 additions and 35 deletions

View File

@@ -1,5 +1,7 @@
FROM openjdk:21
COPY target/ArtisanConnectBackend-0.0.1-SNAPSHOT.jar app.jar
WORKDIR /app
ENTRYPOINT ["java","-jar","/app.jar"]
COPY target/ArtisanConnectBackend-0.0.1-SNAPSHOT.jar app/artisan.jar
ENTRYPOINT ["java","-jar","app/artisan.jar"]

View File

@@ -2,10 +2,13 @@ services:
app:
container_name: artisan
build: .
networks:
- artisan_network
depends_on:
- db
networks:
- artisan_network
ports:
- '8085:8080'
db:
container_name: db

View File

@@ -1,13 +1,27 @@
package _11.asktpk.artisanconnectbackend;
import jakarta.annotation.PostConstruct;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
@SpringBootApplication
public class ArtisanConnectBackendApplication {
private final Environment environment;
public ArtisanConnectBackendApplication(Environment environment) {
this.environment = environment;
}
public static void main(String[] args) {
SpringApplication.run(ArtisanConnectBackendApplication.class, args);
}
@PostConstruct
public void logDataSourceUrl() {
System.out.println("Datasource URL: " + environment.getProperty("spring.datasource.url"));
}
}

View File

@@ -1,14 +1,17 @@
package _11.asktpk.artisanconnectbackend.controller;
import _11.asktpk.artisanconnectbackend.service.ClientService;
import _11.asktpk.artisanconnectbackend.service.ImageService;
import _11.asktpk.artisanconnectbackend.service.NoticeService;
import _11.asktpk.artisanconnectbackend.dto.NoticeDTO;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.http.HttpStatus;
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;
@@ -20,10 +23,12 @@ import java.util.List;
public class NoticeController {
private final NoticeService noticeService;
private final ClientService clientService;
private final ImageService imageService;
public NoticeController(NoticeService noticeService, ClientService clientService) {
public NoticeController(NoticeService noticeService, ClientService clientService, ImageService imageService) {
this.noticeService = noticeService;
this.clientService = clientService;
this.imageService = imageService;
}
@GetMapping("/get/all")
@@ -110,12 +115,16 @@ public class NoticeController {
@PostMapping("/upload/{id}")
public ResponseEntity<String> uploadImage(@PathVariable("id") Long id, @RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Nie przesłano pliku.");
}
if (!noticeService.noticeExists(id)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Nie znaleziono ogłoszenia o ID: " + id);
}
try {
String filePath = noticeService.saveImage(id, file);
String filePath = noticeService.saveImage("./app/images/notices/", id, file);
return ResponseEntity.ok("Zdjęcie zapisane pod ścieżką: " + filePath);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Błąd podczas zapisywania zdjęcia: " + e.getMessage());
@@ -123,37 +132,56 @@ public class NoticeController {
}
@GetMapping("/images/{id}")
public ResponseEntity<List<String>> getAllImages(@PathVariable("id") Long id) {
@GetMapping("/images/{noticeId}/{imageIndex}")
public ResponseEntity<byte[]> getImage(@PathVariable Long noticeId, @PathVariable Integer imageIndex) {
try {
Path directoryPath = Paths.get("src/main/resources/static/images/notices/" + id);
if (!Files.exists(directoryPath) || !Files.isDirectory(directoryPath)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
if (!noticeService.noticeExists(noticeId)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
List<String> imagePaths = new ArrayList<>();
Files.list(directoryPath).forEach(file -> {
if (Files.isRegularFile(file) && Files.isReadable(file)) {
imagePaths.add(file.toString());
}
});
NoticeDTO notice = noticeService.getNoticeById(noticeId);
List<String> imagePaths = notice.getImages();
if (imagePaths.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
if (imagePaths == null || imagePaths.isEmpty() || imageIndex >= imagePaths.size() || imageIndex < 0) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
return ResponseEntity.ok(imagePaths);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
String imagePath = imagePaths.get(imageIndex);
byte[] imageBytes = imageService.getImageBytes(imagePath);
MediaType mediaType = imageService.getMediaTypeForImage(imagePath);
return ResponseEntity
.ok()
.contentType(mediaType)
.body(imageBytes);
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
// @GetMapping("/check/{id}")
// public ResponseEntity<String> checkNotice(@PathVariable("id") long id) {
// if (noticeService.noticeExists(id)) {
// return ResponseEntity.ok("Ogłoszenie o ID " + id + " istnieje.");
// } else {
// return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Nie znaleziono ogłoszenia o ID: " + id);
// }
// }
@GetMapping("/images/{id}")
public ResponseEntity<List<String>> getNoticeImageUrls(@PathVariable("id") Long id) {
try {
if (!noticeService.noticeExists(id)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
NoticeDTO notice = noticeService.getNoticeById(id);
List<String> imagePaths = notice.getImages();
if (imagePaths == null || imagePaths.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
// Zamiast przesyłać bajty, zwracamy listę URL-i do obrazów
List<String> imageUrls = new ArrayList<>();
for (int i = 0; i < imagePaths.size(); i++) {
imageUrls.add("/api/v1/notices/images/" + id + "/" + i);
}
return ResponseEntity.ok(imageUrls);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}

View File

@@ -0,0 +1,38 @@
package _11.asktpk.artisanconnectbackend.service;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Service
public class ImageService {
public byte[] getImageBytes(String imagePath) throws IOException {
Path path = Paths.get(imagePath);
return Files.readAllBytes(path);
}
public Resource getImageAsResource(String imagePath) throws IOException {
Path path = Paths.get(imagePath);
Resource resource = new UrlResource(path.toUri());
if(resource.exists() && resource.isReadable()) {
return resource;
} else {
throw new IOException("Nie można odczytać obrazu: " + imagePath);
}
}
public MediaType getMediaTypeForImage(String imagePath) {
return MediaTypeFactory
.getMediaType(imagePath)
.orElse(MediaType.APPLICATION_OCTET_STREAM);
}
}

View File

@@ -113,8 +113,8 @@ public class NoticeService {
}
}
public String saveImage(Long noticeId, MultipartFile file) throws IOException {
String uploadDir = "src/main/resources/static/images/notices/" + noticeId;
public String saveImage(String uploadFolder, Long noticeId, MultipartFile file) throws IOException {
String uploadDir = uploadFolder + noticeId;
Path uploadPath = Paths.get(uploadDir);
if (!Files.exists(uploadPath)) {
@@ -141,12 +141,11 @@ public class NoticeService {
.orElse(0);
fileName = baseName + (maxNumber + 1) + extension;
} else {
throw new IOException("Nie można znaleźć nazwy pliku");
}
//koniec szukania nazwy pliku
if(fileName == null) {
throw new IOException("Nie można znaleźć nazwy pliku");
}
Path filePath = uploadPath.resolve(fileName);
Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);