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?

686voto

Christophe L Punkte 13082

Zur einfachen Manipulation von URLs / Pfaden / Parametern / etc. können Sie die Spring-Funktion UriComponentsBuilder Klasse, um eine URL-Vorlage mit Platzhaltern für die Parameter zu erstellen, und geben Sie dann den Wert für diese Parameter in der RestOperations.exchange(...) anrufen. Das ist sauberer als die manuelle Verkettung von Zeichenketten, und es kümmert sich um die URL-Kodierung für Sie:

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

268voto

pavel Punkte 2894

Die uriVariablen werden auch in der Abfragezeichenfolge erweitert. Der folgende Aufruf erweitert zum Beispiel die Werte für Konto und Name:

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

Die eigentliche Anfrage-URL lautet also

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

Schauen Sie sich HierarchicalUriComponents.expandInternal(UriTemplateVariables) für weitere Details an. Die Version von Spring ist 3.1.3.

73voto

dustin.schultz Punkte 12496

Spätestens seit Spring 3 wird statt der Verwendung von UriComponentsBuilder um die URL zu erstellen (was ein wenig umständlich ist), viele der RestTemplate Methoden akzeptieren Platzhalter im Pfad für Parameter (nicht nur exchange ).

Aus der Dokumentation:

Viele der RestTemplate Methoden akzeptiert eine URI-Vorlage und URI Template-Variablen, entweder als String v Map<String,String> .

Zum Beispiel mit einer String vararg:

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

Oder mit einer 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);

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

Wenn Sie sich die JavaDoc para RestTemplate und suchen Sie nach "URI-Vorlage", dann können Sie sehen, mit welchen Methoden Sie Platzhalter verwenden können.

37voto

Kripesh Bista Punkte 421
    String uri = http://my-rest-url.org/rest/account/{account};

    Map<String, String> uriParam = new HashMap<>();
    uriParam.put("account", "my_account");

    UriComponents builder = UriComponentsBuilder.fromHttpUrl(uri)
                .queryParam("pageSize","2")
                        .queryParam("page","0")
                        .queryParam("name","my_name").build();

    HttpEntity<String> requestEntity = new HttpEntity<>(null, getHeaders());

    ResponseEntity<String> strResponse = restTemplate.exchange(builder.toUriString(),HttpMethod.GET, requestEntity,
                        String.class,uriParam);

    //final URL: http://my-rest-url.org/rest/account/my_account?pageSize=2&page=0&name=my_name

RestTemplate: Erstellung dynamischer URI mit UriComponents (URI-Variable und Anfrageparameter)

32voto

Elwood Punkte 4229

OK, ich bin also ein Idiot und verwechsle Abfrageparameter mit Url-Parametern. Ich hatte irgendwie gehofft, dass es einen schöneren Weg geben würde, meine Abfrageparameter zu füllen, als einen hässlichen, verketteten String, aber so ist es nun mal. Es ist einfach ein Fall von Build die URL mit den richtigen Parametern. Wenn Sie es als String übergeben, kümmert sich Spring auch um die Kodierung für Sie.

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