Spring RestTemplate GET con parámetros
Tengo que realizar una REST
llamada que incluya encabezados personalizados y parámetros de consulta. Lo configuro HttpEntity
solo 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 servlet
no 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 POST
un cuerpo de solicitud y sin parámetros de consulta, funciona bien.
¿Alguien tiene alguna idea?
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
);
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.
Desde al menos Spring 3, en lugar de usar UriComponentsBuilder
para construir la URL (que es un poco detallada), muchos de los RestTemplate
métodos aceptan marcadores de posición en la ruta para los parámetros (no solo exchange
).
De la documentación:
Muchos de los
RestTemplate
métodos aceptan una plantilla de URI y variables de plantilla de URI, ya sea comoString
vararg o comoMap<String,String>
.Por ejemplo con un
String
vararg: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 .