Refactor PrestashopClient to normalize base URL, enhance URL building, and improve raw query handling
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// package à adapter si besoin
|
||||
package fr.gameovergne.api.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -19,166 +20,133 @@ import java.util.Map;
|
||||
public class PrestashopClient {
|
||||
|
||||
private final RestClient client;
|
||||
private final String baseUrl; // ex: https://shop.gameovergne.fr/api
|
||||
private final String baseUrl;
|
||||
private final String apiKey;
|
||||
|
||||
public PrestashopClient(
|
||||
@Value("${prestashop.api.base-url}") String baseUrl,
|
||||
@Value("${prestashop.api.key}") String apiKey
|
||||
) {
|
||||
// on normalise pour éviter les doubles /
|
||||
if (baseUrl.endsWith("/")) {
|
||||
this.baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
|
||||
} else {
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
this.baseUrl = baseUrl; // ex: https://shop.gameovergne.fr/api
|
||||
this.apiKey = apiKey;
|
||||
|
||||
log.info("[PrestaShop] Base URL = {}", this.baseUrl);
|
||||
log.info("[PrestaShop] API key length = {}", apiKey != null ? apiKey.length() : 0);
|
||||
log.info("[PrestaShop] Base URL = {}", baseUrl);
|
||||
log.info("[PrestaShop] API key length = {}", apiKey.length());
|
||||
|
||||
this.client = RestClient.builder()
|
||||
.defaultHeaders(headers -> {
|
||||
headers.set(HttpHeaders.USER_AGENT, "curl/8.10.1");
|
||||
// Accept JSON par défaut ; pour XML on surchargera dans les méthodes XML
|
||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON, MediaType.ALL));
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
private String normalizePath(String path) {
|
||||
if (path == null || path.isBlank()) return "";
|
||||
// /products -> products
|
||||
return path.startsWith("/") ? path.substring(1) : path;
|
||||
// ------------------------------------------------------------------------
|
||||
// Outil interne : construit l’URL complète baseUrl + path + ?ws_key=...¶ms...
|
||||
// ------------------------------------------------------------------------
|
||||
private String buildUrl(String path, MultiValueMap<String, String> params) {
|
||||
StringBuilder full = new StringBuilder();
|
||||
|
||||
// baseUrl
|
||||
full.append(baseUrl);
|
||||
|
||||
// path
|
||||
if (path != null && !path.isBlank()) {
|
||||
boolean baseEndsWithSlash = baseUrl.endsWith("/");
|
||||
boolean pathStartsWithSlash = path.startsWith("/");
|
||||
|
||||
if (baseEndsWithSlash && pathStartsWithSlash) {
|
||||
full.append(path.substring(1));
|
||||
} else if (!baseEndsWithSlash && !pathStartsWithSlash) {
|
||||
full.append("/").append(path);
|
||||
} else {
|
||||
full.append(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construit une URL complète Presta avec ws_key et params encodés UNE SEULE FOIS.
|
||||
* Utilisée par toutes les méthodes "admin" (getJson/getXml/postXml/putXml/delete).
|
||||
*/
|
||||
private String buildUrl(String path, MultiValueMap<String, String> params) {
|
||||
StringBuilder fullUrl = new StringBuilder();
|
||||
|
||||
fullUrl.append(baseUrl)
|
||||
.append("/")
|
||||
.append(normalizePath(path));
|
||||
|
||||
// auth par ws_key (remplace Basic Auth)
|
||||
String encodedKey = URLEncoder.encode(apiKey, StandardCharsets.UTF_8);
|
||||
fullUrl.append("?ws_key=").append(encodedKey);
|
||||
// ws_key en premier param
|
||||
full.append("?ws_key=").append(URLEncoder.encode(apiKey, StandardCharsets.UTF_8));
|
||||
|
||||
if (params != null && !params.isEmpty()) {
|
||||
for (Map.Entry<String, List<String>> entry : params.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
String key = entry.getKey();
|
||||
for (String value : entry.getValue()) {
|
||||
fullUrl.append("&")
|
||||
.append(URLEncoder.encode(name, StandardCharsets.UTF_8))
|
||||
full.append("&")
|
||||
.append(URLEncoder.encode(key, StandardCharsets.UTF_8))
|
||||
.append("=")
|
||||
.append(URLEncoder.encode(value, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fullUrl.toString();
|
||||
String url = full.toString();
|
||||
log.debug("[PrestaShop] Built URL = {}", url);
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilisé par le contrôleur proxy : on reçoit la query string brute
|
||||
* (déjà encodée, ex: display=%5Bid,name,active%5D&output_format=JSON)
|
||||
* -> on NE LA RÉ-ENCODE PAS.
|
||||
*/
|
||||
public String getWithRawQuery(String resource, String rawQuery) {
|
||||
StringBuilder fullUrl = new StringBuilder();
|
||||
|
||||
fullUrl.append(baseUrl)
|
||||
.append("/")
|
||||
.append(normalizePath(resource));
|
||||
|
||||
String encodedKey = URLEncoder.encode(apiKey, StandardCharsets.UTF_8);
|
||||
fullUrl.append("?ws_key=").append(encodedKey);
|
||||
|
||||
if (rawQuery != null && !rawQuery.isBlank()) {
|
||||
fullUrl.append("&").append(rawQuery);
|
||||
}
|
||||
|
||||
String url = fullUrl.toString();
|
||||
log.info("[PrestaShop] RAW GET via ws_key = {}", url);
|
||||
|
||||
return client.get()
|
||||
.uri(URI.create(url))
|
||||
.accept(MediaType.APPLICATION_JSON, MediaType.ALL)
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// GET JSON (utilisé PARTOUT dans PrestashopAdminService)
|
||||
// -----------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// GET JSON (utilisé partout dans PrestashopAdminService)
|
||||
// ------------------------------------------------------------------------
|
||||
public String getJson(String path, MultiValueMap<String, String> params) {
|
||||
String url = buildUrl(path, params);
|
||||
log.info("[PrestaShop] GET JSON {}", url);
|
||||
|
||||
return client.get()
|
||||
.uri(URI.create(url))
|
||||
.accept(MediaType.APPLICATION_JSON, MediaType.ALL)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// GET XML
|
||||
// -----------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// GET XML (utilisé pour certains appels de stock, produit, etc.)
|
||||
// ------------------------------------------------------------------------
|
||||
public String getXml(String path, MultiValueMap<String, String> params) {
|
||||
String url = buildUrl(path, params);
|
||||
log.info("[PrestaShop] GET XML {}", url);
|
||||
|
||||
return client.get()
|
||||
.uri(URI.create(url))
|
||||
.accept(MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.ALL)
|
||||
.accept(MediaType.APPLICATION_XML)
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// POST XML
|
||||
// -----------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// POST XML (création catégorie/produit/etc.)
|
||||
// ------------------------------------------------------------------------
|
||||
public String postXml(String path, MultiValueMap<String, String> params, String xmlBody) {
|
||||
String url = buildUrl(path, params);
|
||||
log.info("[PrestaShop] POST XML {}", url);
|
||||
log.info("[PrestaShop] POST XML {} (body length={})", url, xmlBody != null ? xmlBody.length() : 0);
|
||||
|
||||
return client.post()
|
||||
.uri(URI.create(url))
|
||||
.contentType(MediaType.APPLICATION_XML)
|
||||
.accept(MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.ALL)
|
||||
.body(xmlBody)
|
||||
.accept(MediaType.APPLICATION_XML)
|
||||
.body(xmlBody != null ? xmlBody : "")
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// PUT XML
|
||||
// -----------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// PUT XML (update catégorie/produit/stock/etc.)
|
||||
// ------------------------------------------------------------------------
|
||||
public String putXml(String path, MultiValueMap<String, String> params, String xmlBody) {
|
||||
String url = buildUrl(path, params);
|
||||
log.info("[PrestaShop] PUT XML {}", url);
|
||||
log.info("[PrestaShop] PUT XML {} (body length={})", url, xmlBody != null ? xmlBody.length() : 0);
|
||||
|
||||
return client.put()
|
||||
.uri(URI.create(url))
|
||||
.contentType(MediaType.APPLICATION_XML)
|
||||
.accept(MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.ALL)
|
||||
.body(xmlBody)
|
||||
.accept(MediaType.APPLICATION_XML)
|
||||
.body(xmlBody != null ? xmlBody : "")
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// DELETE
|
||||
// -----------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// DELETE (suppression ressource)
|
||||
// ------------------------------------------------------------------------
|
||||
public void delete(String path, MultiValueMap<String, String> params) {
|
||||
String url = buildUrl(path, params);
|
||||
log.info("[PrestaShop] DELETE {}", url);
|
||||
@@ -186,6 +154,43 @@ public class PrestashopClient {
|
||||
client.delete()
|
||||
.uri(URI.create(url))
|
||||
.retrieve()
|
||||
.body(Void.class);
|
||||
.toBodilessEntity();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Spécial proxy GET brut : on garde la query telle quelle (déjà encodée)
|
||||
// ------------------------------------------------------------------------
|
||||
public String getWithRawQuery(String resource, String rawQuery) {
|
||||
try {
|
||||
StringBuilder fullUrl = new StringBuilder();
|
||||
fullUrl.append(baseUrl);
|
||||
// baseUrl : https://shop.gameovergne.fr/api
|
||||
if (!baseUrl.endsWith("/")) {
|
||||
fullUrl.append("/");
|
||||
}
|
||||
// resource : "categories", "products", ...
|
||||
fullUrl.append(resource);
|
||||
|
||||
// ws_key
|
||||
String encodedKey = URLEncoder.encode(apiKey, StandardCharsets.UTF_8);
|
||||
fullUrl.append("?ws_key=").append(encodedKey);
|
||||
|
||||
// rawQuery = "display=%5Bid,name,active%5D&output_format=JSON"
|
||||
if (rawQuery != null && !rawQuery.isBlank()) {
|
||||
fullUrl.append("&").append(rawQuery); // surtout ne pas réencoder
|
||||
}
|
||||
|
||||
String urlString = fullUrl.toString();
|
||||
log.info("[PrestaShop] RAW GET via ws_key = {}", urlString);
|
||||
|
||||
return client.get()
|
||||
.uri(URI.create(urlString))
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[PrestaShop] getWithRawQuery error for resource={} rawQuery={}", resource, rawQuery, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user