Preciso fazer uma REST
chamada que inclua cabeçalhos personalizados e parâmetros de consulta. Defino meu HttpEntity
com apenas os cabeçalhos (sem corpo) e uso o RestTemplate.exchange()
método da seguinte maneira:
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);
Isso falha no final do cliente, pois dispatcher servlet
não é possível resolver a solicitação para um manipulador. Após a depuração, parece que os parâmetros de solicitação não estão sendo enviados.
Quando eu faço uma troca com um POST
corpo de solicitação usando e sem parâmetros de consulta, ele funciona muito bem.
Alguém tem alguma idéia?
exchange
paragetForEntity
:restTemplate.getForEntity(builder.build().encode().toUri(), String.class);
por simplicidade.exchange
e fornecer umParameterizedTypeReference
. O exemplo pode ser ainda mais simplificado, substituindobuilder.build().encode().toUri()
porbuilder.toUriString()
.builder.toUriString()
As uriVariables também são expandidas na string de consulta. Por exemplo, a seguinte chamada expandirá os valores para conta e nome:
portanto, o URL da solicitação real será
Veja HierarchicalUriComponents.expandInternal (UriTemplateVariables) para obter mais detalhes. A versão do Spring é 3.1.3.
fonte
UriComponentsBuilder
tanto como ele está causando-lo para gerar uma métrica diferente para cada pedido, comMicrometer
RestTemplate
possui métodos paralelos para especificar uma matriz posicional de valores (Object... uriVariables
) ou um mapa de valores nomeados (Map<String, ?> uriVariables
). Parece que a versão do mapa é o que você quer:restTemplate.exchange(url, HttpMethod.GET, httpEntity, clazz, urlVariablesMap)
.Como pelo menos o Spring 3, em vez de usar
UriComponentsBuilder
para criar a URL (que é um pouco detalhada), muitos dosRestTemplate
métodos aceitam espaços reservados no caminho para parâmetros (não apenasexchange
).A partir da documentação:
Referência: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#rest-resttemplate-uri
Se você olhar para o JavaDoc para
RestTemplate
e procure por "Template URI", você pode ver quais métodos você pode usar espaços reservados com.fonte
OK, estou sendo um idiota e confundindo parâmetros de consulta com parâmetros de URL. Eu meio que esperava que houvesse uma maneira melhor de preencher meus parâmetros de consulta em vez de uma String concatenada feia, mas aqui estamos. É simplesmente um caso de criar a URL com os parâmetros corretos. Se você o passar como String Spring, também cuidará da codificação.
fonte
Eu estava tentando algo semelhante, e o exemplo do RoboSpice me ajudou a resolver isso :
fonte
RestTemplate: criar URI dinâmico usando UriComponents (variável URI e parâmetros de solicitação)
fonte
Convertendo um mapa de hash em uma sequência de parâmetros de consulta:
fonte
Eu adoto uma abordagem diferente, você pode concordar ou não, mas quero controlar o arquivo .properties em vez do código Java compilado
Arquivo interno application.properties
endpoint.url = https: // yourHost / resource? requestParam1 = {0} & requestParam2 = {1}
O código Java está aqui, você pode escrever se ou alternar a condição para descobrir se o URL do terminal no arquivo .properties possui @PathVariable (contém {}) ou @RequestParam (yourURL? Key = value) etc ... e, em seguida, invoque o método de acordo. dessa forma, é dinâmico e não precisa codificar alterações no futuro balcão único ...
Estou tentando dar mais ideias do que o código real aqui ... tente escrever um método genérico para @RequestParam e @PathVariable etc ... e chame de acordo quando necessário
fonte
No Spring Web 4.3.6, também vejo
Isso significa que você não precisa criar um mapa feio
Então, se você tem esse URL
Você pode fazer
ou
fonte
fonte
Se você passar parâmetros não parametrizados para o RestTemplate, terá uma métrica para todos os URLs diferentes que passar, considerando os parâmetros. Você gostaria de usar URLs parametrizados:
ao invés de
O segundo caso é o que você obtém usando a classe UriComponentsBuilder.
Uma maneira de implementar o primeiro comportamento é o seguinte:
fonte
Se o seu URL for
http://localhost:8080/context path?msisdn={msisdn}&email={email}
então
funciona para o método de troca resttemplate conforme descrito por você
fonte