Refactor PrestashopClient and PrestashopProxyController for improved API request handling and response management
This commit is contained in:
@@ -16,65 +16,92 @@ public class PrestashopProxyController {
|
|||||||
this.prestashopClient = prestashopClient;
|
this.prestashopClient = prestashopClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utilitaire pour extraire /products, /products/446, etc.
|
/**
|
||||||
|
* Extrait le path Presta à partir de la requête entrante.
|
||||||
|
* Exemple :
|
||||||
|
* - requestURI = /api/ps/products/446
|
||||||
|
* - retourne /products/446
|
||||||
|
*/
|
||||||
private String extractPath(HttpServletRequest request) {
|
private String extractPath(HttpServletRequest request) {
|
||||||
String fullPath = request.getRequestURI(); // ex: /api/ps/products/446
|
String fullPath = request.getRequestURI(); // ex: /api/ps/products/446
|
||||||
String contextPath = request.getContextPath(); // souvent ""
|
String contextPath = request.getContextPath(); // souvent ""
|
||||||
String relative = fullPath.substring(contextPath.length()); // /api/ps/products/446
|
String relative = fullPath.substring(contextPath.length()); // /api/ps/products/446
|
||||||
return relative.replaceFirst("^/api/ps", ""); // => /products/446
|
|
||||||
|
// On enlève le préfixe /api/ps => /products/446
|
||||||
|
return relative.replaceFirst("^/api/ps", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- GET ----------
|
||||||
|
|
||||||
@GetMapping("/**")
|
@GetMapping("/**")
|
||||||
public ResponseEntity<String> proxyGet(HttpServletRequest request) {
|
public ResponseEntity<String> proxyGet(HttpServletRequest request) {
|
||||||
String path = extractPath(request);
|
String path = extractPath(request);
|
||||||
String query = request.getQueryString();
|
String query = request.getQueryString(); // ex: display=full&filter[id_product]=123
|
||||||
|
|
||||||
String body = prestashopClient.get(path, query);
|
String body = prestashopClient.get(path, query);
|
||||||
|
|
||||||
|
// On sait qu'on force output_format=JSON côté client.get(...)
|
||||||
return ResponseEntity
|
return ResponseEntity
|
||||||
.ok()
|
.ok()
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.body(body);
|
.body(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/**")
|
// ---------- POST ----------
|
||||||
public ResponseEntity<String> proxyPut(HttpServletRequest request,
|
|
||||||
@RequestBody String body) {
|
|
||||||
String path = extractPath(request);
|
|
||||||
String query = request.getQueryString();
|
|
||||||
|
|
||||||
String responseBody = prestashopClient.put(path, query, body);
|
|
||||||
|
|
||||||
return ResponseEntity
|
|
||||||
.ok()
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.body(responseBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/**")
|
@PostMapping("/**")
|
||||||
public ResponseEntity<String> proxyPost(HttpServletRequest request,
|
public ResponseEntity<String> proxyPost(
|
||||||
@RequestBody String body) {
|
HttpServletRequest request,
|
||||||
|
@RequestBody String bodyFromFront
|
||||||
|
) {
|
||||||
String path = extractPath(request);
|
String path = extractPath(request);
|
||||||
String query = request.getQueryString();
|
String query = request.getQueryString();
|
||||||
|
|
||||||
String responseBody = prestashopClient.post(path, query, body);
|
String body = prestashopClient.post(path, query, bodyFromFront);
|
||||||
|
|
||||||
|
// Si Angular demande output_format=JSON dans la query, on peut renvoyer JSON,
|
||||||
|
// sinon ce sera typiquement du XML. Dans tous les cas on renvoie le raw body.
|
||||||
|
MediaType mediaType = (query != null && query.contains("output_format=JSON"))
|
||||||
|
? MediaType.APPLICATION_JSON
|
||||||
|
: MediaType.APPLICATION_XML;
|
||||||
|
|
||||||
return ResponseEntity
|
return ResponseEntity
|
||||||
.ok()
|
.ok()
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(mediaType)
|
||||||
.body(responseBody);
|
.body(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- PUT ----------
|
||||||
|
|
||||||
|
@PutMapping("/**")
|
||||||
|
public ResponseEntity<String> proxyPut(
|
||||||
|
HttpServletRequest request,
|
||||||
|
@RequestBody String bodyFromFront
|
||||||
|
) {
|
||||||
|
String path = extractPath(request);
|
||||||
|
String query = request.getQueryString();
|
||||||
|
|
||||||
|
String body = prestashopClient.put(path, query, bodyFromFront);
|
||||||
|
|
||||||
|
MediaType mediaType = (query != null && query.contains("output_format=JSON"))
|
||||||
|
? MediaType.APPLICATION_JSON
|
||||||
|
: MediaType.APPLICATION_XML;
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.ok()
|
||||||
|
.contentType(mediaType)
|
||||||
|
.body(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- DELETE ----------
|
||||||
|
|
||||||
@DeleteMapping("/**")
|
@DeleteMapping("/**")
|
||||||
public ResponseEntity<String> proxyDelete(HttpServletRequest request) {
|
public ResponseEntity<Void> proxyDelete(HttpServletRequest request) {
|
||||||
String path = extractPath(request);
|
String path = extractPath(request);
|
||||||
String query = request.getQueryString();
|
String query = request.getQueryString();
|
||||||
|
|
||||||
String responseBody = prestashopClient.delete(path, query);
|
prestashopClient.delete(path, query);
|
||||||
|
|
||||||
return ResponseEntity
|
return ResponseEntity.noContent().build();
|
||||||
.ok()
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.body(responseBody);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.*;
|
import org.springframework.http.*;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.HttpStatusCodeException;
|
|
||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
@@ -30,18 +29,45 @@ public class PrestashopClient {
|
|||||||
this.basicAuth = basicAuth;
|
this.basicAuth = basicAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================
|
/**
|
||||||
// GET : on force JSON + full
|
* Construit l'URL finale vers PrestaShop en propageant la query d'origine.
|
||||||
// =========================
|
*
|
||||||
public String get(String path, String ignoredQuery) {
|
* @param path ex: "/products", "/products/446"
|
||||||
|
* @param query queryString brute reçue côté API (peut être null)
|
||||||
|
* @param addDefaultFormatAndDisplay si true, ajoute output_format=JSON et display=full
|
||||||
|
*/
|
||||||
|
private String buildUrl(String path, String query, boolean addDefaultFormatAndDisplay) {
|
||||||
UriComponentsBuilder builder = UriComponentsBuilder
|
UriComponentsBuilder builder = UriComponentsBuilder
|
||||||
.fromHttpUrl(baseUrl)
|
.fromHttpUrl(baseUrl)
|
||||||
.path("/api")
|
.path("/api")
|
||||||
.path(path)
|
.path(path);
|
||||||
.queryParam("output_format", "JSON")
|
|
||||||
.queryParam("display", "full");
|
|
||||||
|
|
||||||
String url = builder.build(true).toUriString();
|
// On propage TOUT ce que le front a mis (display, filter[...], etc.)
|
||||||
|
if (query != null && !query.isBlank()) {
|
||||||
|
builder.query(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addDefaultFormatAndDisplay) {
|
||||||
|
// Si le front n'a pas mis output_format, on force JSON
|
||||||
|
if (query == null || !query.contains("output_format=")) {
|
||||||
|
builder.queryParam("output_format", "JSON");
|
||||||
|
}
|
||||||
|
// Si le front n'a pas mis display, on force full
|
||||||
|
if (query == null || !query.contains("display=")) {
|
||||||
|
builder.queryParam("display", "full");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build(true).toUriString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET générique vers PrestaShop.
|
||||||
|
* - Propage la queryString Angular (display, filter[...], etc.)
|
||||||
|
* - Ajoute output_format=JSON & display=full si absents.
|
||||||
|
*/
|
||||||
|
public String get(String path, String query) {
|
||||||
|
String url = buildUrl(path, query, true);
|
||||||
|
|
||||||
log.info("[PrestaShop] GET {}", url);
|
log.info("[PrestaShop] GET {}", url);
|
||||||
|
|
||||||
@@ -59,10 +85,8 @@ public class PrestashopClient {
|
|||||||
String.class
|
String.class
|
||||||
);
|
);
|
||||||
|
|
||||||
log.info("[PrestaShop] Réponse GET {} pour {}", response.getStatusCode(), url);
|
|
||||||
|
|
||||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||||
throw new RuntimeException("PrestaShop returned non-2xx status: "
|
throw new RuntimeException("PrestaShop returned non-2xx status on GET: "
|
||||||
+ response.getStatusCode() + " for URL " + url);
|
+ response.getStatusCode() + " for URL " + url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,79 +97,20 @@ public class PrestashopClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================
|
/**
|
||||||
// PUT : on respecte la query du front
|
* POST générique vers PrestaShop.
|
||||||
// =========================
|
* On propage la query telle quelle (si Angular met output_format=JSON, etc.).
|
||||||
public String put(String path, String query, String body) {
|
* Le body est du XML (templates construits côté Angular).
|
||||||
UriComponentsBuilder builder = UriComponentsBuilder
|
*/
|
||||||
.fromHttpUrl(baseUrl)
|
|
||||||
.path("/api")
|
|
||||||
.path(path);
|
|
||||||
|
|
||||||
if (query != null && !query.isBlank()) {
|
|
||||||
// on laisse Angular décider (ex: output_format=JSON)
|
|
||||||
builder.query(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = builder.build(true).toUriString();
|
|
||||||
log.info("[PrestaShop] PUT {}", url);
|
|
||||||
log.debug("[PrestaShop] PUT body = {}", body);
|
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
|
||||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
||||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
|
||||||
|
|
||||||
HttpEntity<String> entity = new HttpEntity<>(body, headers);
|
|
||||||
|
|
||||||
try {
|
|
||||||
ResponseEntity<String> response = restTemplate.exchange(
|
|
||||||
url,
|
|
||||||
HttpMethod.PUT,
|
|
||||||
entity,
|
|
||||||
String.class
|
|
||||||
);
|
|
||||||
|
|
||||||
log.info("[PrestaShop] Réponse PUT {} pour {}", response.getStatusCode(), url);
|
|
||||||
|
|
||||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
|
||||||
throw new RuntimeException("PrestaShop returned non-2xx status: "
|
|
||||||
+ response.getStatusCode() + " for URL " + url);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
// Ici on log le body d'erreur de Presta !
|
|
||||||
log.error("[PrestaShop] Erreur PUT {} status={} body={}",
|
|
||||||
url, e.getStatusCode(), e.getResponseBodyAsString(), e);
|
|
||||||
throw new RuntimeException("Erreur PUT PrestaShop", e);
|
|
||||||
} catch (RestClientException e) {
|
|
||||||
log.error("[PrestaShop] Erreur PUT {}", url, e);
|
|
||||||
throw new RuntimeException("Erreur PUT PrestaShop", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================
|
|
||||||
// POST : création
|
|
||||||
// =========================
|
|
||||||
public String post(String path, String query, String body) {
|
public String post(String path, String query, String body) {
|
||||||
UriComponentsBuilder builder = UriComponentsBuilder
|
String url = buildUrl(path, query, false);
|
||||||
.fromHttpUrl(baseUrl)
|
|
||||||
.path("/api")
|
|
||||||
.path(path);
|
|
||||||
|
|
||||||
if (query != null && !query.isBlank()) {
|
|
||||||
builder.query(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = builder.build(true).toUriString();
|
|
||||||
log.info("[PrestaShop] POST {}", url);
|
log.info("[PrestaShop] POST {}", url);
|
||||||
log.debug("[PrestaShop] POST body = {}", body);
|
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
||||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
headers.setContentType(MediaType.APPLICATION_XML);
|
||||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
headers.setAccept(List.of(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML));
|
||||||
|
|
||||||
HttpEntity<String> entity = new HttpEntity<>(body, headers);
|
HttpEntity<String> entity = new HttpEntity<>(body, headers);
|
||||||
|
|
||||||
@@ -157,43 +122,66 @@ public class PrestashopClient {
|
|||||||
String.class
|
String.class
|
||||||
);
|
);
|
||||||
|
|
||||||
log.info("[PrestaShop] Réponse POST {} pour {}", response.getStatusCode(), url);
|
|
||||||
|
|
||||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||||
throw new RuntimeException("PrestaShop returned non-2xx status: "
|
throw new RuntimeException("PrestaShop returned non-2xx status on POST: "
|
||||||
+ response.getStatusCode() + " for URL " + url);
|
+ response.getStatusCode() + " for URL " + url
|
||||||
|
+ " - response: " + response.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.getBody();
|
return response.getBody();
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
log.error("[PrestaShop] Erreur POST {} status={} body={}",
|
|
||||||
url, e.getStatusCode(), e.getResponseBodyAsString(), e);
|
|
||||||
throw new RuntimeException("Erreur POST PrestaShop", e);
|
|
||||||
} catch (RestClientException e) {
|
} catch (RestClientException e) {
|
||||||
log.error("[PrestaShop] Erreur POST {}", url, e);
|
log.error("[PrestaShop] Erreur POST {}", url, e);
|
||||||
throw new RuntimeException("Erreur POST PrestaShop", e);
|
throw new RuntimeException("Erreur POST PrestaShop", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================
|
/**
|
||||||
// DELETE : suppression
|
* PUT générique vers PrestaShop.
|
||||||
// =========================
|
* Le body est du XML (templates construits côté Angular).
|
||||||
public String delete(String path, String query) {
|
*/
|
||||||
UriComponentsBuilder builder = UriComponentsBuilder
|
public String put(String path, String query, String body) {
|
||||||
.fromHttpUrl(baseUrl)
|
String url = buildUrl(path, query, false);
|
||||||
.path("/api")
|
|
||||||
.path(path);
|
|
||||||
|
|
||||||
if (query != null && !query.isBlank()) {
|
log.info("[PrestaShop] PUT {}", url);
|
||||||
builder.query(query);
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
||||||
|
headers.setContentType(MediaType.APPLICATION_XML);
|
||||||
|
headers.setAccept(List.of(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML));
|
||||||
|
|
||||||
|
HttpEntity<String> entity = new HttpEntity<>(body, headers);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ResponseEntity<String> response = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.PUT,
|
||||||
|
entity,
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||||
|
throw new RuntimeException("PrestaShop returned non-2xx status on PUT: "
|
||||||
|
+ response.getStatusCode() + " for URL " + url
|
||||||
|
+ " - response: " + response.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = builder.build(true).toUriString();
|
return response.getBody();
|
||||||
|
} catch (RestClientException e) {
|
||||||
|
log.error("[PrestaShop] Erreur PUT {}", url, e);
|
||||||
|
throw new RuntimeException("Erreur PUT PrestaShop", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE générique vers PrestaShop.
|
||||||
|
*/
|
||||||
|
public void delete(String path, String query) {
|
||||||
|
String url = buildUrl(path, query, false);
|
||||||
|
|
||||||
log.info("[PrestaShop] DELETE {}", url);
|
log.info("[PrestaShop] DELETE {}", url);
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
||||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
|
||||||
|
|
||||||
HttpEntity<Void> entity = new HttpEntity<>(headers);
|
HttpEntity<Void> entity = new HttpEntity<>(headers);
|
||||||
|
|
||||||
@@ -205,18 +193,11 @@ public class PrestashopClient {
|
|||||||
String.class
|
String.class
|
||||||
);
|
);
|
||||||
|
|
||||||
log.info("[PrestaShop] Réponse DELETE {} pour {}", response.getStatusCode(), url);
|
|
||||||
|
|
||||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||||
throw new RuntimeException("PrestaShop returned non-2xx status: "
|
throw new RuntimeException("PrestaShop returned non-2xx status on DELETE: "
|
||||||
+ response.getStatusCode() + " for URL " + url);
|
+ response.getStatusCode() + " for URL " + url
|
||||||
|
+ " - response: " + response.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
log.error("[PrestaShop] Erreur DELETE {} status={} body={}",
|
|
||||||
url, e.getStatusCode(), e.getResponseBodyAsString(), e);
|
|
||||||
throw new RuntimeException("Erreur DELETE PrestaShop", e);
|
|
||||||
} catch (RestClientException e) {
|
} catch (RestClientException e) {
|
||||||
log.error("[PrestaShop] Erreur DELETE {}", url, e);
|
log.error("[PrestaShop] Erreur DELETE {}", url, e);
|
||||||
throw new RuntimeException("Erreur DELETE PrestaShop", e);
|
throw new RuntimeException("Erreur DELETE PrestaShop", e);
|
||||||
|
|||||||
Reference in New Issue
Block a user