J'essaie de faire un appel de repos simple avec ressorts resttemplate:
private void doLogout(String endpointUrl, String sessionId) {
template.getForObject("http://{enpointUrl}?method=logout&session={sessionId}", Object.class,
endpointUrl, sessionId);
}
Où la variable endpointUrl contient quelque chose comme service.hôte.com/api/service.php
Malheureusement, mon appel génère un org.springframework.web.client.ResourceAccessException: erreur d'E/S: service.Host.com% 2Fapi% 2Fservice.php
Donc, spring semble encoder ma chaîne endpointUrl avant lors de la création de l'URL. Existe-t-il un moyen simple d'empêcher le printemps de faire cela?
Cordialement
Il n'y a pas de moyen facile de faire cela. Les variables URI sont généralement destinées à un élément de chemin ou à un paramètre de chaîne de requête. Vous essayez de faire passer plusieurs éléments.
Une solution de contournement consiste à utiliser UriTemplate
pour générer l'URL avec les variables URI telles que vous les avez, puis le décoder par URL et le transmettre à votre RestTemplate
.
String url = "http://{enpointUrl}?method=logout&session={sessionId}";
URI expanded = new UriTemplate(url).expand(endpointUrl, sessionId); // this is what RestTemplate uses
url = URLDecoder.decode(expanded.toString(), "UTF-8"); // Java.net class
template.getForObject(url, Object.class);
Cela dépend de la version de Spring que vous utilisez. Si votre version est trop ancienne, par exemple la version 3.0.6.RELEASE, vous ne disposerez pas de la même facilité que UriComponentsBuilder
avec votre fichier jar spring-web.
Ce dont vous avez besoin est d'empêcher Spring RestTemplate de coder l'URL. Ce que tu pourrais faire c'est:
import Java.net.URI;
StringBuilder builder = new StringBuilder("http://");
builder.append(endpointUrl);
builder.append("?method=logout&session=");
builder.append(sessionId);
URI uri = URI.create(builder.toString());
restTemplate.getForObject(uri, Object.class);
Je l'ai testé avec Spring version 3.0.6.LELEASE, et cela fonctionne.
Dans un mot, au lieu d'utiliser restTemplate.getForObject(String url, Object.class)
, utilisez restTemplate.getForObject(Java.net.URI uri, Object.class)
Vous pouvez utiliser la variante surchargée qui utilise un fichier Java.net.URI à la place getForObject public (URL URI, Classe responseType) lève RestClientException
De La propre documentation de Spring
UriComponents uriComponents =
UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build()
.expand("42", "21")
.encode();
URI uri = uriComponents.toUri();
Exemple complet avec en-têtes, corps, pour tout HttpMethod et ResponseType pourrait ressembler à
String url = "http://google.com/{path}?param1={param1Value}¶m2={param2Value}";
Object body = null;
HttpEntity request = new HttpEntity(body, new HttpHeaders());
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("path", "search");
uriVariables.put("param1Value", "value1");
uriVariables.put("param2Value", "value2");
ResponseEntity<Void> responseEntity = restTemplate.exchange(url, HttpMethod.POST, request, Void.class, uriVariables)
//responseEntity.getBody()
En fait, il utilisera la même méthode UriTemplate et expand