web-dev-qa-db-fra.com

Utilisation de RestTemplate au printemps. Exception: pas assez de variables disponibles pour se développer

J'essaie d'accéder au contenu d'une API et je dois envoyer une URL à l'aide de RestTemplate.

String url1 = "http://api.example.com/Search?key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort={\"price\":\"desc\"}";

OutputPage page = restTemplate.getForObject(url1, OutputPage .class);

Mais je reçois l'erreur suivante.

Exception in thread "main" Java.lang.IllegalArgumentException: Not enough variable values available to expand '"price"'
at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.Java:284)
at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.Java:220)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.Java:317)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.Java:46)
at org.springframework.web.util.UriComponents.expand(UriComponents.Java:162)
at org.springframework.web.util.UriTemplate.expand(UriTemplate.Java:119)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.Java:501)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.Java:239)
at hello.Application.main(Application.Java:26)

Si je supprime les critères de tri, cela fonctionne correctement ... Je dois analyser le code JSON à l'aide des critères de tri ... ".

Merci

22
user3311403

La cause principale est que RestTemplate considère les accolades {...} dans l'URL donnée comme espace réservé pour les variables URI et tente de les remplacer en fonction de leur nom. Par exemple

{pageSize}

essaierait d’obtenir une variable URI appelée pageSize. Ces variables d'URI sont spécifiées avec certaines des autres méthodes surchargées getForObject . Vous n'en avez fourni aucune, mais votre URL en attend une, aussi la méthode lève-t-elle une exception.

Une solution consiste à créer un objet String contenant la valeur

String sort = "{\"price\":\"desc\"}";

et fournissez une vraie variable URI dans votre URL

String url1 = "http://api.example.com/Search?key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort={sort}";

Vous appelez votre getForObject() comme si

OutputPage page = restTemplate.getForObject(url1, OutputPage.class, sort);

Je vous suggère fortement de ne pas envoyer de JSON dans un paramètre de requête d'une requête GET mais de l'envoyer dans le corps d'une requête POST.

43
Sotirios Delimanolis

Vous pouvez URL encoder les valeurs de paramètre:

String url1 = "http://api.example.com/Search?key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort=";

org.Apache.commons.codec.net.URLCodec codec = new org.Apache.commons.codec.net.URLCodec();
url1 = url1 + codec.encode("{\"price\":\"desc\"}");
OutputPage page = restTemplate.getForObject(url1, OutputPage.class);
5
Thor

Si la solution suggérée par sotirios-delimanolis est un peu difficile à implémenter dans un scénario, et si la chaîne d'URI contenant des accolades et d'autres caractères est correcte, il peut être plus simple de transmettre la chaîne d'URI codée à une méthode de RestTemplate qui frappe le serveur ReST.

La chaîne d'URI peut être construite avec UriComponentsBuilder.build () , codée avec UriComponents.encode () et envoyée avec RestTemplate.exchange () comme ceci:

public ResponseEntity<Object> requestRestServer()
{
    HttpEntity<?> entity = new HttpEntity<>(requestHeaders);
    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(rawValidUrl)
            .queryParams(
                    (LinkedMultiValueMap<String, String>) allRequestParams);
    UriComponents uriComponents = builder.build().encode();
    ResponseEntity<Object> responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET,
            entity, String.class);
    return responseEntity;
}

La construction, le codage et l'extraction d'URI ont été séparés pour plus de clarté dans l'extrait de code ci-dessus.

2
noob

vous pouvez simplement ajouter une variable à l'URL et transmettre la valeur de la variable restTemplate.postForObject méthode.

String url1 = "http://api.example.com/Search? 
key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort={data}";
String data="{\"price\":\"desc\"}";
OutputPage page = restTemplate.getForObject(url1, OutputPage.class, data);
0
Somnath Singh