RestTemplateを使用してサードパーティのRestサービス呼び出しを行う

1.はじめに

RestTemplateこれはSpringが提供するRestfulサービスを呼び出す抽象化レイヤーであり、Restfulサービスとの通信を簡素化し、不要な詳細を隠し、アプリケーションでRestfulサービスをよりエレガントに呼び出すことができますただし、Spring 5.0以降RestTemplateはメンテナンスモードであり、新機能は開発されず、一部の定期的なメンテナンスのみが行われます。Springでは、同期、非同期、およびStreamを同時にサポートする別のAPI - WebClientを使用することをお勧めしますしかし、Spring MVCの下では、現時点でこれ以上の選択肢はありません。

2. RestTemplateの使用シナリオ

SMS、エクスプレスクエリ、天気予報などのプロジェクトではサードパーティのRest APIサービスをよく使用します。限り、これらの第三者休憩APIは、あなたが使用することができRestTemplate、それらを呼び出すこと。

3. RestTemplateを初期化する

プロジェクトでSpring MVCを使用している限り、プロジェクトはすでに統合されていRestTemplateます。しかし、通常、この種は、自動的に注入されていない春のIoCの多くあるため、コンテナのREST APIは特別なを持って、その構造のクラスをカスタマイズすることがより柔軟にRestTemplateBuilder自動的に注入された春のIoCコンテナ。次のように初期化できます。

package cn.felord.rest.webclient;

import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * @author felord.cn
 * @since 14:58
 **/
@Component
public class SomeWeb {

    private final RestTemplateBuilder restTemplateBuilder;

    public SomeWeb(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplateBuilder = restTemplateBuilder;
    }

    public RestTemplate restTemplate() {
        // 通过 builder 定制
        return restTemplateBuilder.requestFactory(OkHttp3ClientHttpRequestFactory::new).
                build();
    }
}
复制代码

ベストプラクティス:サードパーティの各サービスを可能な限りカスタマイズしRestTemplate、これらのサードパーティのプロセスに完全な一貫性がない限り、それを公に使用しないようにします。

2.1 RestTemplate最下層

デフォルトでは、RestTemplate使用java.net.HttpURLConnectionそれを使用した場合の実装として、しかし(例えば401など)異常な状態に応答して、例外がスローされるので、我々はそれを使用していません。私たちは、に切り替えることができネッティーApacheのHttpComponentsokHttpクライアントライブラリのデフォルトの実装、参照2requestFactory(ClientHttpRequestFactory factory)のアクセス方法は、自分で実現することが可能とClientHttpRequestFactoryドッキングアクセス他のサードパーティのライブラリ。ここではokHttpを使用していますこれらのサードパーティライブラリによって提供される機能をカスタマイズしてRestTemplate、リクエストタイムアウトの設定など、機能を拡張できます

3.一般的な方法のシナリオの例

RestTemplateすべてのRestfulスタイルのメソッドをサポートします。ニーズに応じて選択できます。ここでは、いくつかの一般的なメソッドのみを紹介します。すべてのメソッドはURIテンプレートとURIパラメータをサポートし、次の記述をサポートします。

# 类似 spring mvc 中的 @PathVariable
https://api.apiopen.top/{method}
复制代码

3.1 {get | post} ForEntity

取得要求には応答にマッピングされるResponseEntity<T>オブジェクト、ラッパーオブジェクト本体の応答に応じてインチ 次のコードを使用して、きれいな女性の5枚の写真をランダムにリクエストします。印刷して表示できます。

    @Autowired
    RestTemplate restTemplate;

    void contextLoads() {
        String url = "https://api.apiopen.top/getImages?page=0&count=5";
        ResponseEntity<String> responseEntity = restTemplate
                .getForEntity(url,String.class);
        String body = responseEntity.getBody();
        System.out.println("body = " + body);
    }
复制代码

上記のメソッドは、順番に変数パラメーターに変更されます。

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
        ResponseEntity<String> responseEntity = restTemplate
                .getForEntity(url,String.class,0,5);
        String body = responseEntity.getBody();
        System.out.println("body = " + body);
复制代码

または使用Map<String,Object>

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
        HashMap<String, Object> uriParams = new HashMap<>();
        uriParams.put("page", 0);
        uriParams.put("count", 5);
        ResponseEntity<String> responseEntity = restTemplate
                .getForEntity(url, String.class, uriParams);
        String body = responseEntity.getBody();
        System.out.println("body = " + body);
复制代码

ポスト要求は、付加的な可能性が通過するnullVOオブジェクト、またはMultiValueMap最終的に封入される、要求本体パラメータを運ぶために

org.springframework.http.HttpEntity オブジェクト。オブジェクトには、次の2つの部分を含めることができます。

  • リクエストボディオブジェクト。エンティティVOを使用できます。MultiValueMap
  • リクエストヘッダーオブジェクト、 org.springframework.http.HttpHeaders
 String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<UserVO> httpEntity = new HttpEntity<>(new UserVO("userName"), headers);
        HashMap<String, Object> uriParams = new HashMap<>();
        uriParams.put("page", 0);
        uriParams.put("count", 5);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class, uriParams);
复制代码

上記はPostリクエストを呼び出し、リクエストボディとリクエストヘッダーを運ぶ例です。

3.2 {get | post} ForObject

我々はまた、直接にマッピングされた対応できるPOJO、もちろん、あなたは、構造体の結果に対応するために必要十分承知している、ためにマッピングすることをお勧めしますString構造を確認してください。例を挙げますが、他の例は3.1を参照しています。

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
        HashMap<String, Object> uriParams = new HashMap<>();
        uriParams.put("page", 0);
        uriParams.put("count", 5);
        String forObject = restTemplate.getForObject(url, String.class, uriParams);
        System.out.println("forObject = " + forObject);
复制代码

3.3 headForHeaders

このメソッドはすべてのURIテンプレート宣言リソースのヘッダーを取得するために使用されます

        String url = "https://api.apiopen.top/getImages?page={page}&count={count}";
        HashMap<String, Object> uriParams = new HashMap<>();
        uriParams.put("page", 0);
        uriParams.put("count", 5);
        HttpHeaders httpHeaders = restTemplate.headForHeaders(url, uriParams);
        System.out.println(httpHeaders);
复制代码

結果は次のとおりです。

[Access-Control-Allow-Headers:"Content-Type, x-requested-with, X-Custom-Header, Authorization", Access-Control-Allow-Methods:"POST, GET, OPTIONS, DELETE", Access-Control-Allow-Origin:"*", Access-Control-Max-Age:"3600", Cache-Control:"private", Content-Length:"608", Content-Type:"application/json;charset=UTF-8", Date:"Tue, 14 Apr 2020 15:25:19 GMT", Expires:"Thu, 01 Jan 1970 00:00:00 GMT"]
复制代码

3.4 postForLocation

このPostオペレーションは完全なリソースを返しませんが、新しく作成されたリソースURIを返します。たとえば、ファイルをアップロードすると、リソースのリクエストパスが返されます。

3.5配置/削除

putリクエストとdeleteリクエストについては、前のAPIを参照してください。

3.6 optionsForAllow

このメソッドはGET、POST、PUT、DELETEなどURIで許可されているすべてのリクエストメソッドの1つ以上取得します。

3.7交換

このメソッドは、GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACEをサポートする一般的なリクエストメソッドです。上記のメソッドで満足できない場合は、このメソッドを使用してカスタマイズできます。このメソッドは、より柔軟なAPIを提供します。たとえば、次のことができます。GETメソッドのリクエストヘッダーカスタマイズしJwtトークンやその他の操作に入れることは、getForObject比類のないものです。

4.まとめ

RestTemplateこれは非常に便利なリクエストコーディネーターであり、柔軟性を失うことなく、呼び出しサービスの複雑さを保護します。しかし、それは歴史の段階から撤退していることは注目に値します。優秀なプログラマーもキャリアを変える日はありませんか?

关注公众号:Felordcn获取更多资讯

個人ブログ:https://felord.cn

おすすめ

転載: juejin.im/post/5e9933e5e51d45471263f714