397 Stimmen

Spring RestTemplate GET mit Parametern

Ich muss eine REST Aufruf, der benutzerdefinierte Kopfzeilen und Abfrageparameter enthält. Ich setze meine HttpEntity mit nur den Kopfzeilen (ohne Körper), und ich verwende die RestTemplate.exchange() Methode wie folgt:

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);

Dies schlägt auf der Client-Seite mit der dispatcher servlet nicht in der Lage ist, die Anfrage an einen Handler weiterzuleiten. Nach der Fehlersuche sieht es so aus, als ob die Anfrageparameter nicht gesendet werden.

Wenn ich einen Austausch mit einem POST mit einem Request Body und ohne Query-Parameter funktioniert es einwandfrei.

Hat jemand eine Idee?

21voto

datu-puti Punkte 1156

Ich habe etwas Ähnliches versucht, und das RoboSpice-Beispiel hat mir geholfen, es zu verstehen :

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

HttpEntity<String> request = new HttpEntity<>(input, createHeader());

String url = "http://awesomesite.org";
Uri.Builder uriBuilder = Uri.parse(url).buildUpon();
uriBuilder.appendQueryParameter(key, value);
uriBuilder.appendQueryParameter(key, value);
...

String url = uriBuilder.build().toString();

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

17voto

Ilya Lysenko Punkte 1621

Konvertierung einer Hash-Map in eine Zeichenkette von Abfrageparametern:

Map<String, 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);

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
for (Map.Entry<String, String> entry : params.entrySet()) {
    builder.queryParam(entry.getKey(), entry.getValue());
}

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

HttpEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, new HttpEntity(headers), String.class);

11voto

Kalpesh Soni Punkte 6079

In Spring Web 4.3.6 sehe ich auch

public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)

Das bedeutet, dass Sie keine hässliche Karte erstellen müssen.

Wenn Sie also diese Url haben

http://my-url/action?param1={param1}&param2={param2}

Sie können entweder

restTemplate.getForObject(url, Response.class, param1, param2)

oder

restTemplate.getForObject(url, Response.class, param [])

5voto

Java_Fire_Within Punkte 559

Ich verfolge einen anderen Ansatz, Sie mögen dem zustimmen oder nicht, aber ich möchte die Kontrolle über die .properties-Datei statt über den kompilierten Java-Code

Innerhalb der Datei application.properties

endpoint.url = https://yourHost/resource?requestParam1= {0}&requestParam2={1}

Java-Code geht hier, können Sie schreiben, wenn oder Switch-Bedingung, um herauszufinden, wenn Endpunkt-URL in .properties-Datei hat @PathVariable (enthält {}) oder @RequestParam (IhreURL?key=value) etc... dann Methode entsprechend aufrufen... auf diese Weise seine dynamische und nicht brauchen, um Code-Änderung in Zukunft ein Stop-Shop...

Ich versuche, hier mehr eine Idee als tatsächlichen Code zu vermitteln. Versuchen Sie, eine generische Methode für @RequestParam und @PathVariable usw. zu schreiben und bei Bedarf entsprechend aufzurufen.

  @Value("${endpoint.url}")
  private String endpointURL;
  // you can use variable args feature in Java
  public String requestParamMethodNameHere(String value1, String value2) {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate
           .getMessageConverters()
           .add(new MappingJackson2HttpMessageConverter());

    HttpHeaders headers = new HttpHeaders();
    headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
    HttpEntity<String> entity = new HttpEntity<>(headers);

    try {
      String formatted_URL = MessageFormat.format(endpointURL, value1, value2);
      ResponseEntity<String> response = restTemplate.exchange(
                    formatted_URL ,
                    HttpMethod.GET,
                    entity,
                    String.class);
     return response.getBody();
    } catch (Exception e) { e.printStackTrace(); }

4voto

Dalton Punkte 400

Wenn Sie nicht parametrisierte Parameter für RestTemplate übergeben, haben Sie eine Metrik für jede einzelne unterschiedliche URL, die Sie übergeben, unter Berücksichtigung der Parameter. Sie möchten parametrisierte URLs verwenden:

http://my-url/action?param1={param1}&param2={param2}

anstelle von

http://my-url/action?param1=XXXX&param2=YYYY

Der zweite Fall ist das, was Sie erhalten, wenn Sie die Klasse UriComponentsBuilder verwenden.

Eine Möglichkeit, das erste Verhalten zu implementieren, ist die folgende:

Map<String, Object> params = new HashMap<>();
params.put("param1", "XXXX");
params.put("param2", "YYYY");

String url = "http://my-url/action?%s";

String parametrizedArgs = params.keySet().stream().map(k ->
    String.format("%s={%s}", k, k)
).collect(Collectors.joining("&"));

HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<String> entity = new HttpEntity<>(headers);

restTemplate.exchange(String.format(url, parametrizedArgs), HttpMethod.GET, entity, String.class, params);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X