Spring RestTemplate GET con parámetros

Resuelto Elwood asked hace 12 años • 18 respuestas

Tengo que realizar una RESTllamada que incluya encabezados personalizados y parámetros de consulta. Lo configuro HttpEntitysolo con los encabezados (sin cuerpo) y uso el RestTemplate.exchange()método de la siguiente manera:

HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");

Map<String, String> params = new HashMap<String, String>();
params.put("msisdn", msisdn);
params.put("email", email);
params.put("clientVersion", clientVersion);
params.put("clientType", clientType);
params.put("issuerName", issuerName);
params.put("applicationName", applicationName);

HttpEntity entity = new HttpEntity(headers);

HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class, params);

Esto falla en el extremo del cliente y dispatcher servletno puede resolver la solicitud a un controlador. Después de depurarlo, parece que los parámetros de la solicitud no se envían.

Cuando hago un intercambio usando POSTun cuerpo de solicitud y sin parámetros de consulta, funciona bien.

¿Alguien tiene alguna idea?

Elwood avatar Nov 28 '11 21:11 Elwood
Aceptado

Para manipular fácilmente URL/ruta/parámetros/etc., puede usar la clase UriComponentsBuilder de Spring para crear una plantilla de URL con marcadores de posición para los parámetros y luego proporcionar el valor de esos parámetros en la RestOperations.exchange(...)llamada. Es más limpio que concatenar cadenas manualmente y se encarga de la codificación de la URL por usted:

HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
HttpEntity<?> entity = new HttpEntity<>(headers);

String urlTemplate = UriComponentsBuilder.fromHttpUrl(url)
        .queryParam("msisdn", "{msisdn}")
        .queryParam("email", "{email}")
        .queryParam("clientVersion", "{clientVersion}")
        .queryParam("clientType", "{clientType}")
        .queryParam("issuerName", "{issuerName}")
        .queryParam("applicationName", "{applicationName}")
        .encode()
        .toUriString();

Map<String, ?> params = new HashMap<>();
params.put("msisdn", msisdn);
params.put("email", email);
params.put("clientVersion", clientVersion);
params.put("clientType", clientType);
params.put("issuerName", issuerName);
params.put("applicationName", applicationName);

HttpEntity<String> response = restOperations.exchange(
        urlTemplate,
        HttpMethod.GET,
        entity,
        String.class,
        params
);
Christophe L avatar Aug 21 '2014 19:08 Christophe L

Las uriVariables también se expanden en la cadena de consulta. Por ejemplo, la siguiente llamada expandirá los valores tanto para la cuenta como para el nombre:

restTemplate.exchange("http://my-rest-url.org/rest/account/{account}?name={name}",
    HttpMethod.GET,
    httpEntity,
    clazz,
    "my-account",
    "my-name"
);

entonces la URL de solicitud real será

http://my-rest-url.org/rest/account/my-account?name=my-name

Mire HierarchicalUriComponents.expandInternal(UriTemplateVariables) para obtener más detalles. La versión de Spring es 3.1.3.

pavel avatar May 21 '2013 18:05 pavel

Desde al menos Spring 3, en lugar de usar UriComponentsBuilderpara construir la URL (que es un poco detallada), muchos de los RestTemplatemétodos aceptan marcadores de posición en la ruta para los parámetros (no solo exchange).

De la documentación:

Muchos de los RestTemplatemétodos aceptan una plantilla de URI y variables de plantilla de URI, ya sea como Stringvararg o como Map<String,String>.

Por ejemplo con un Stringvararg:

restTemplate.getForObject(
   "http://example.com/hotels/{hotel}/rooms/{room}", String.class, "42", "21");

O con un Map<String, String>:

Map<String, String> vars = new HashMap<>();
vars.put("hotel", "42");
vars.put("room", "21");

restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{room}", 
    String.class, vars);

Referencia: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#rest-resttemplate-uri

Si consulta el JavaDocRestTemplate y busca "Plantilla URI", podrá ver con qué métodos puede utilizar marcadores de posición .

dustin.schultz avatar Apr 29 '2018 17:04 dustin.schultz