Refactor PrestashopClient to streamline image upload process and enhance error handling

This commit is contained in:
Vincent Guillet
2025-12-03 14:30:34 +01:00
parent df98dfe38e
commit fa7a1c2f26

View File

@@ -2,6 +2,7 @@ package fr.gameovergne.api.service.prestashop;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*; import org.springframework.http.*;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
@@ -233,74 +234,49 @@ public class PrestashopClient {
* On envoie directement les bytes du fichier avec le bon content-type (image/jpeg, image/png, ...). * On envoie directement les bytes du fichier avec le bon content-type (image/jpeg, image/png, ...).
*/ */
public ResponseEntity<String> uploadProductImage(String productId, public ResponseEntity<String> uploadProductImage(
String rawQuery, String productId,
MultipartFile imageFile) { String rawQuery,
MultipartFile imageFile
) {
try { try {
// 1) URL complète vers Presta // construction de l'URL relative (le RestClient a déjà baseUrl)
StringBuilder urlBuilder = new StringBuilder(baseUrl) StringBuilder pathBuilder = new StringBuilder("/images/products/")
.append("/images/products/")
.append(productId); .append(productId);
if (rawQuery != null && !rawQuery.isBlank()) { if (rawQuery != null && !rawQuery.isBlank()) {
urlBuilder.append("?").append(rawQuery); pathBuilder.append('?').append(rawQuery);
} }
String url = urlBuilder.toString(); String path = pathBuilder.toString();
byte[] bytes = imageFile.getBytes(); byte[] bytes = imageFile.getBytes();
// 2) Headers de la PART "image"
HttpHeaders partHeaders = new HttpHeaders();
MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM;
if (imageFile.getContentType() != null && !imageFile.getContentType().isBlank()) {
try {
mediaType = MediaType.parseMediaType(imageFile.getContentType());
} catch (Exception ignored) {
// on garde OCTET_STREAM
}
}
partHeaders.setContentType(mediaType);
// Content-Disposition: form-data; name="image"; filename="xxx.jpg"
ContentDisposition disposition = ContentDisposition
.builder("form-data")
.name("image")
.filename(imageFile.getOriginalFilename())
.build();
partHeaders.setContentDisposition(disposition);
// 3) Entity de la PART (équivalent ByteArrayContent en C#)
HttpEntity<byte[]> imagePart = new HttpEntity<>(bytes, partHeaders);
// 4) Corps multipart : clé "image"
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("image", imagePart);
log.info("[PrestaShop] POST (image multipart) {} (size={} bytes, contentType={})", log.info("[PrestaShop] POST (image multipart) {} (size={} bytes, contentType={})",
url, bytes.length, mediaType); baseUrl + path, bytes.length, imageFile.getContentType());
// 5) Appel Presta via RestClient // Ressource avec un filename pour que Spring pose bien le Content-Disposition
ByteArrayResource fileResource = new ByteArrayResource(bytes) {
@Override
public String getFilename() {
String name = imageFile.getOriginalFilename();
return (name != null && !name.isBlank()) ? name : "image.jpg";
}
};
// corps multipart : clé -> "image"
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("image", fileResource);
// Envoi de la requête multipart/form-data
return client.post() return client.post()
.uri(url) .uri(path)
.contentType(MediaType.MULTIPART_FORM_DATA) .contentType(MediaType.MULTIPART_FORM_DATA)
.body(body) .body(body)
.retrieve() .retrieve()
.toEntity(String.class); .toEntity(String.class);
} catch (HttpClientErrorException e) {
// on log ce que renvoie Presta et on renvoie tel quel au front
log.error("[PrestaShop] POST image error {} : {}",
e.getStatusCode().value(), e.getResponseBodyAsString());
return ResponseEntity
.status(e.getStatusCode())
.contentType(MediaType.APPLICATION_XML)
.body(e.getResponseBodyAsString());
} catch (IOException e) { } catch (IOException e) {
log.error("[PrestaShop] Erreur lecture fichier image", e); log.error("[PrestaShop] Erreur lecture fichier image", e);
return ResponseEntity throw new RuntimeException("Erreur lors de la lecture du fichier image", e);
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("<prestashop><errors><error><message>Erreur lecture image côté API</message></error></errors></prestashop>");
} }
} }
} }