Refactor PrestashopClient to enhance image upload handling and improve error logging
This commit is contained in:
@@ -2,13 +2,11 @@ package fr.gameovergne.api.service.prestashop;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestClientResponseException;
|
||||
@@ -239,42 +237,70 @@ public class PrestashopClient {
|
||||
String rawQuery,
|
||||
MultipartFile imageFile) {
|
||||
try {
|
||||
StringBuilder url = new StringBuilder(baseUrl)
|
||||
// 1) URL complète vers Presta
|
||||
StringBuilder urlBuilder = new StringBuilder(baseUrl)
|
||||
.append("/images/products/")
|
||||
.append(productId);
|
||||
|
||||
if (rawQuery != null && !rawQuery.isBlank()) {
|
||||
url.append("?").append(rawQuery);
|
||||
urlBuilder.append("?").append(rawQuery);
|
||||
}
|
||||
String url = urlBuilder.toString();
|
||||
|
||||
// Corps multipart avec un champ "image" comme demandé par PrestaShop
|
||||
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<>();
|
||||
|
||||
ByteArrayResource imageResource = new ByteArrayResource(imageFile.getBytes()) {
|
||||
@Override
|
||||
public String getFilename() {
|
||||
// PrestaShop veut un filename, même si ce n'est pas critique
|
||||
return imageFile.getOriginalFilename() != null
|
||||
? imageFile.getOriginalFilename()
|
||||
: "image.jpg";
|
||||
}
|
||||
};
|
||||
|
||||
body.add("image", imageResource); // 👈 IMPORTANT : le nom du champ = "image"
|
||||
body.add("image", imagePart);
|
||||
|
||||
log.info("[PrestaShop] POST (image multipart) {} (size={} bytes, contentType={})",
|
||||
url, imageFile.getSize(), imageFile.getContentType());
|
||||
url, bytes.length, mediaType);
|
||||
|
||||
return client
|
||||
.post()
|
||||
.uri(url.toString())
|
||||
// 5) Appel Presta via RestClient
|
||||
return client.post()
|
||||
.uri(url)
|
||||
.contentType(MediaType.MULTIPART_FORM_DATA)
|
||||
.body(body)
|
||||
.retrieve()
|
||||
.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) {
|
||||
throw new RuntimeException("Erreur lors de la lecture du fichier image", e);
|
||||
log.error("[PrestaShop] Erreur lecture fichier image", e);
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.body("<prestashop><errors><error><message>Erreur lecture image côté API</message></error></errors></prestashop>");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user