Refactor PrestashopProxyController to simplify image upload API path

This commit is contained in:
Vincent Guillet
2025-12-03 13:51:54 +01:00
parent f317d15ac5
commit 65559bbb48

View File

@@ -2,10 +2,12 @@ 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.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClient; import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestClientException;
@@ -229,56 +231,50 @@ public class PrestashopClient {
/** /**
* Upload d'une image produit vers PrestaShop : * Upload d'une image produit vers PrestaShop :
* POST /api/images/products/{productId} * POST /api/images/products/{productId}
* * <p>
* 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, String rawQuery, MultipartFile imageFile) {
String uri = baseUrl + "/images/products/" + productId;
if (rawQuery != null && !rawQuery.isBlank()) {
uri = uri + "?" + rawQuery;
}
// Content-Type de l'image : on essaie de respecter celui fourni par le client,
// sinon on force sur du JPEG par défaut.
String ct = imageFile.getContentType();
MediaType mediaType = (ct != null && !ct.isBlank())
? MediaType.parseMediaType(ct)
: MediaType.IMAGE_JPEG;
log.info("[PrestaShop] POST (image) {} (size={} bytes, contentType={})",
uri, imageFile.getSize(), mediaType);
public ResponseEntity<String> uploadProductImage(String productId,
String rawQuery,
MultipartFile imageFile) {
try { try {
byte[] bytes = imageFile.getBytes(); StringBuilder url = new StringBuilder(baseUrl)
.append("/images/products/")
.append(productId);
return client.post() if (rawQuery != null && !rawQuery.isBlank()) {
.uri(uri) url.append("?").append(rawQuery);
.contentType(mediaType) }
.body(bytes)
// Corps multipart avec un champ "image" comme demandé par PrestaShop
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"
log.info("[PrestaShop] POST (image multipart) {} (size={} bytes, contentType={})",
url, imageFile.getSize(), imageFile.getContentType());
return client
.post()
.uri(url.toString())
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(body)
.retrieve() .retrieve()
.toEntity(String.class); .toEntity(String.class);
} catch (RestClientResponseException ex) { } catch (IOException e) {
// Erreur fonctionnelle renvoyée par Presta (taille, format, etc.) throw new RuntimeException("Erreur lors de la lecture du fichier image", e);
log.error("[PrestaShop] POST image error {} : {}", ex.getRawStatusCode(), ex.getResponseBodyAsString());
return ResponseEntity
.status(ex.getRawStatusCode())
.contentType(MediaType.APPLICATION_XML)
.body(ex.getResponseBodyAsString());
} catch (IOException ex) {
// Problème de lecture du fichier envoyé depuis le client
log.error("[PrestaShop] POST image, erreur lecture fichier", ex);
return ResponseEntity
.status(400)
.contentType(MediaType.TEXT_PLAIN)
.body("Invalid image file");
} catch (RestClientException ex) {
// Cas réseau / technique
log.error("[PrestaShop] POST image technical error", ex);
return ResponseEntity
.status(502)
.contentType(MediaType.TEXT_PLAIN)
.body("Error while calling PrestaShop WebService");
} }
} }
} }