Verwenden des Spring RestTemplate Interceptor

Verwenden des Spring RestTemplate Interceptor

1. Überblick

In diesem Tutorial erfahren Sie, wie Sie einen Spring-Link implementieren: / rest-template Interceptor.

Wir werden ein Beispiel durchgehen, in dem wir einen Interceptor erstellen, der der Antwort einen benutzerdefinierten Header hinzufügt.

2. Interceptor-Verwendungsszenarien

Neben der Änderung des Headers sind einige der anderen Anwendungsfälle, in denen der Interceptor vonRestTemplatenützlich ist, folgende:

  • Anforderungs- und Antwortprotokollierung

  • Wiederholen der Anforderungen mit einer konfigurierbaren Backoff-Strategie

  • Anforderungsablehnung basierend auf bestimmten Anforderungsparametern

  • Ändern der Anforderungs-URL-Adresse

3. Erstellen des Interceptors

In den meisten Programmierparadigmen unterstützt das Spring-Framework voninterceptors are an essential part that enables programmers to control the execution by intercepting it.auch eine Vielzahl von Interceptors für verschiedene Zwecke.

Mit SpringRestTemplate können wir Interceptors hinzufügen, die die Schnittstelle vonClientHttpRequestInterceptorimplementieren. Dieintercept(HttpRequest, byte[], ClientHttpRequestExecution)-Methode dieser Schnittstelle fängt die angegebene Anforderung ab und gibt die Antwort zurück, indem sie uns Zugriff auf die Objekterequest,body undexecution gewährt.

Wir werden das ArgumentClientHttpRequestExecutionverwenden, um die eigentliche Ausführung durchzuführen und die Anforderung an die nachfolgende Prozesskette weiterzuleiten.

Als ersten Schritt erstellen wir eine Interceptor-Klasse, die dieClientHttpRequestInterceptor-Schnittstelle implementiert:

public class RestTemplateHeaderModifierInterceptor
  implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(
      HttpRequest request,
      byte[] body,
      ClientHttpRequestExecution execution) throws IOException {

        ClientHttpResponse response = execution.execute(request, body);
        response.getHeaders().add("Foo", "bar");
        return response;
    }
}

Our interceptor will be invoked for every incoming request, und es wird jeder Antwort ein benutzerdefinierter HeaderFoo hinzugefügt, sobald die Ausführung abgeschlossen ist und zurückkehrt.

Da dieintercept()-Methoderequest undbody als Argumente enthielt, ist es auch möglich, Änderungen an der Anforderung vorzunehmen oder sogar die Ausführung der Anforderung unter bestimmten Bedingungen zu verweigern.

4. RestTemplate einrichten

Nachdem wir unseren Interceptor erstellt haben, erstellen wir dieRestTemplate-Bohne und fügen unseren Interceptor hinzu:

@Configuration
public class RestClientConfig {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();

        List interceptors
          = restTemplate.getInterceptors();
        if (CollectionUtils.isEmpty(interceptors)) {
            interceptors = new ArrayList<>();
        }
        interceptors.add(new RestTemplateHeaderModifierInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }
}

In einigen Fällen sind möglicherweise bereits Interceptors zum ObjektRestTemplatehinzugefügt. Um sicherzustellen, dass alles wie erwartet funktioniert, initialisiert unser Code die Interceptor-Liste nur, wenn sie leer ist.

Wie unser Code zeigt, verwenden wir den Standardkonstruktor, um dasRestTemplate-Objekt zu erstellen. In einigen Szenarien müssen wir den Anforderungs- / Antwortstrom jedoch zweimal lesen.

Wenn wir beispielsweise möchten, dass unser Interceptor als Request / Response-Logger fungiert, müssen wir ihn zweimal lesen - das erste Mal vom Interceptor und das zweite Mal vom Client.

Die Standardimplementierung ermöglicht es uns, den Antwortstrom nur einmal zu lesen. Um solchen spezifischen Szenarien gerecht zu werden, bietet Spring eine spezielle Klasse namensBufferingClientHttpRequestFactory.. Wie der Name schon sagt, puffert diese Klasse die Anforderung / Antwort im JVM-Speicher für die mehrfache Verwendung.

So wird dasRestTemplate-Objekt mitBufferingClientHttpRequestFactory initialisiert, um das Zwischenspeichern von Anforderungs- / Antwortströmen zu aktivieren:

RestTemplate restTemplate
  = new RestTemplate(
    new BufferingClientHttpRequestFactory(
      new SimpleClientHttpRequestFactory()
    )
  );

5. Testen Sie unser Beispiel

Hier ist der JUnit-Testfall zum Testen des Abfangjägers vonRestTemplate:

public class RestTemplateItegrationTest {

    @Autowired
    RestTemplate restTemplate;

    @Test
    public void givenRestTemplate_whenRequested_thenLogAndModifyResponse() {
        LoginForm loginForm = new LoginForm("username", "password");
        HttpEntity requestEntity
          = new HttpEntity(loginForm);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        ResponseEntity responseEntity
          = restTemplate.postForEntity(
            "http://httpbin.org/post", requestEntity, String.class
          );

        assertThat(
          responseEntity.getStatusCode(),
          is(equalTo(HttpStatus.OK))
        );
        assertThat(
          responseEntity.getHeaders().get("Foo").get(0),
          is(equalTo("bar"))
        );
    }
}

Hier haben wir den frei gehosteten HTTP-Anforderungs- und Antwortdiensthttps://httpbin.org verwendet, um unsere Daten zu veröffentlichen. Dieser Testservice sendet unseren Anfragetext zusammen mit einigen Metadaten zurück.

6. Fazit

In diesem Tutorial erfahren Sie, wie Sie einen Interceptor einrichten und zumRestTemplate-Objekt hinzufügen. Diese Art von Interzeptoren kann auch zum Filtern, Überwachen und Steuern der eingehenden Anforderungen verwendet werden.

Ein häufiger Anwendungsfall für den Interceptor einesRestTemplateist die Header-Modifikation, die wir in diesem Artikel ausführlich erläutert haben.

Und wie immer finden Sie den Beispielcode überGithub project. Dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.