22 Aralık 2019 Pazar

SpringMVC RestTemplate Sınıfı - Kullanmayın

Giriş
Şu satırı dahil ederiz.
import org.springframework.web.client.RestTemplate;
Bu sınıfın bazı ayarlarını değiştirmek için RestTemplateBuilder kullanılabilir.

WebClient Tercih Edilmeli
Açıklaması şöyle. WebClient nesnesinin kullanılması öneriliyor.
As of 5.0, the non-blocking, reactive org.springframework.web.reactive.client.WebClient offers a modern alternative to the RestTemplate with efficient support for both sync and async, as well as streaming scenarios. The RestTemplate will be deprecated in a future version and will not have major new features added going forward.
Thread Modeli
Açıklaması şöyle
- It is based on a thread per request model, so it can lead to a thread exhaustion state, especially when we deal with the slow third-party APIs.
- It requires additional code for handling error responses.
Converter'lar
Spring bu sınıfa bir sürü converter nesnesini kendiliğinde ekliyor. Açıklaması şöyle.
If you start a Spring application, it takes most configuration to itself, including adding converters (default converters from package org.springframework.http.converter.*: ByteArrayHttpMessageConverter, StringHttpMessageConverter, ResourceHttpMessageConverter, AllEncompassingHttpMessageConverter, MappingJackson2XmlHttpMessageConverter, MappingJackson2HttpMessageConverter).
MappingJackson2HttpMessageConverter sınıfı yazısına bakabilirsiniz.

Kullanım
1.getForEntity(), postForEntity() metodları girdi olarak HttpEntity alır, ResponseEntity verir.

2.getForObject(), postForObject() metodları girdi olarak bizim belirttiğimiz nesneyi alır ve yine bizim belirttiğimiz nesne tipini verir.

3. execute() en genel metoddur ve tam kontrol verir. exchange() ise getForEntity() ve postForEntity() metodlarına göre biraz daha fazla kontrol verir.

ForObject vs ForEntity
Açıklaması şöyle
You may have seen that there are two types of methods which are named slightly different. As an example I can say: getForObject and getForEntity…What is the difference? Let’s see method definitions.

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

Look at the return types!

  • First method returns an object which is having the type of response mapped class. We can access that object’s data if we need them for next logic. That’s all.

  • But in the second method, we get the object wrapped inside a ResponseEntity. There we have more details. Since it is a ResponseEntity, we can access API details like status / status code / headers. This is better when we need to check status and execute the next logic. Ex: — if and only if payment request gives status code 200, send the order response back. We need to call getBody() method to get the exact response data from of the wrapper.


constructor
Şöyle yaparız.
RestTemplate restTemplate = new RestTemplate();
constructor - SimpleClientHttpRequestFactory
SimpleClientHttpRequestFactory yazısına taşıdım.

constructor - HttpComponentsClientHttpRequestFactory 
HttpComponentsClientHttpRequestFactory yazısına taşıdım.

exchange metodu - RequestEntity
exchange() metodu yazısına taşıdım.

execute metodu - URI + HttpMethod + RequestCallback + ResponseCallback
İmzası şöyle.
execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
        @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables)
Açıklaması şöyle. Mümkünse getForObject(), postForObject() tercih edilmeli.
The most generalized way to execute a request, with full control over the preparation of the request and retrieving the response through callback interfaces.
exchange metodu ile farkının açıklaması şöyle. Bu metod ile Bir HttpEntity gönderme ve istenilen Class tipinden sonuç olma imkanı yok! Her şeyi elle yapmak lazım.

Örnek
Şöyle yaparız.
this.restTemplate.execute(uriToCall, HttpMethod.GET, null, clientHttpResponse -> {
    File file= File.createTempFile("download", "tmp");
    StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(file));
});
Örnek
Şöyle yaparız.
RestTemplate restTemplate // = ...;

RequestCallback requestCallback = request -> request.getHeaders()
        .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));

// Streams the response
ResponseExtractor<Void> responseExtractor = response -> {
    // Here I write the response to a file but do what you like
    Path path = Paths.get("http://some/path");
    Files.copy(response.getBody(), path);
    return null;
};
restTemplate.execute(URI.create("www.something.com"), HttpMethod.GET, requestCallback,
  responseExtractor);
getForEntity metodu - URI + Class
Sonuç ResponseEntity<T> tipindendir. T tipi ikinci parametredir. Mümkünse getForObject() metodu tercih edilmeli.

Örnek
Şöyle yaparız.
ResponseEntity<Resource> response = this.restTemplate.getForEntity(uriToCall,
  Resource.class);
Örnek
Şöyle yaparız.
URI uri = ...;
ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
Döndürülen response nesnesinin içindeki string'e getBody() çağrısı ile erişiriz. Veri Json olsun. Kullanmak için şöyle yaparız.
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.getBody());

JsonNode items = root.get("items");
if (items != null && items.size() > 0) {

  for (int i = 0; i < items.size(); i++) {
    JsonNode channelNode = items.get(i);
    channelList.add(channelNode.get("id").asText());
  }
}
getForObject metodu
getForObject metodu yazısına taşıdım

getInterceptors metodu
Şöyle yaparız.
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
Örnek
Şöyle yaparız
BasicAuthorizationInterceptor interceptor = 
  new BasicAuthorizationInterceptor(username, password)
rest.getInterceptors().add(interceptor);
getMessageConverters metodu
Örnek
Açıklaması şöyle.
Note that you should add it to the beginning of the list so that it takes precedence over the default MappingJackson2HttpMessageConverter that Spring has already registered.
Şöyle yaparız.
restTemplate.getMessageConverters().add(0,
  new StringHttpMessageConverter(Charset.forName("utf-8")));
getRequestFactory metodu
Şöyle yaparız.
HttpComponentsClientHttpRequestFactory rf =
  (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
postForEntity metodu
postForEntity metodu yazısına taşıdım.

postForObject metodu
postForObject metodu yazısına taşıdım.

setErrorHandler metodu
Şöyle yaparız.
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
  @Override public boolean hasError(ClientHttpResponse response)
    throws IOException {
    try {
      //Do your stuff
      return super.hasError(response);
    } catch (Exception e) {
      ...;
       return true;
    }
  }

  @Override public void handleError(ClientHttpResponse response)
    throws IOException {
    try {
      //Do your stuff
      super.handleError(response);
    } catch (Exception e) {
      ...
      throw e;
    }
  }
});
setInterceptors metodu
setInterceptors metodu yazısına taşıdım

setUriTemplateHandler metodu
base uri tanımlamaya yarar
Örnek
Şöyle yaparız
import org.springframework.boot.web.client.RootUriTemplateHandler;

String baseUri = ...;
restTemplate.setUriTemplateHandler(new RootUriTemplateHandler(baseUri));

Hiç yorum yok:

Yorum Gönder