Spring Cloud入門から諦めるまで(三):万字解説HTTP利器--RertTemplate


目次
  • クライテリア
  • Rest Template
  • Rest Template一般的な方法
  • Http Message Coverter
  • RestTemplateを作成する
  • 複数のRestTemplate例
  • を作成する.
  • Rest Templateの負荷バランス
  • タイムアウト時間を設定する
  • は、URIオブジェクト
  • を作成する.
  • Rest Template APIは
  • を使用する.
    前言
    Spring Cloudシリーズ:Spring Cloudシリーズの記事をクリックして確認してください.
    Rest Template
    Restt TemplateはSpringが提供するResetサービスにアクセスするためのクライアントであり、Rest TemplateはリモートHttpサービスに便利にアクセスするための様々な方法を提供し、クライアントの作成効率を大幅に向上させることができる.
    レストfulを訪問して、伝統的なApacheのHttpClientがあります.しかし、それに比べて、RertTemplateの方が使いやすいです.
    Rets Templateの一般的な方法
    Restit Templateは異なるHTTP方法に対して、異なる要求方法があります.
    Spring Cloud从入门到放弃(三):万字讲解HTTP利器--RestTemplate_第1张图片注:exchangeとexcuteは上記のHTTP方法、つまりGET方法が使えます.POST方法も使えます.
    Restit Template方法の名称は、命名の約束に従い、第1の部分は呼び出し中のHTTP方法を示し、第2の部分は戻る内容を示す.例えば、この方法はGETを実行し、HTTP応答を選択したオブジェクトタイプに変換して、そのオブジェクトに戻ります.この方法はPOSTを実行し、与えられたオブジェクトをHTTP要求に変換し、その後、HTTP Locationヘッダに応答して、新たに作成されたオブジェクトを見つけることができる.
    ForEntity方法の戻り値はReponse Entityであり、Reponse EntityはSpringのHTTP要求に対する応答のパッケージであり、応答コード、応答ヘッダ、contentType、contentLength、応答メッセージ体などいくつかの重要な要素が含まれている.
    ForObject方法は実際にForEntity関数をさらにパッケージ化します.ForObject方法は、応答体をあなたのほしいオブジェクトタイプに変換します.返信したメッセージ体の内容だけに注目すれば、他の情報には関心がなく、ForObjectを使うことができます.
    以下のとおりです
    //      url,        ,             ,    uri  ( uri    )
    public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,
    			Object... uriVariables) throws RestClientException 
    
    
     :
    
    restTemplate.postForObject(
            "http://example.com/hotels/{hotel}/bookings/{booking}", String.class,"42", "21");
    
    Http Message Coverter
    Restit Templateは、デフォルトでは、HttpMessage Coverterの例を使用して、HTTPメッセージをPOJOに変換するか、POJOからHTTPメッセージに変換する.デフォルトではメインmimeタイプのコンバータを登録しますが、自分のコンバータを作成して、メッセージConverters()属性で注入することもできます.ForObject法のreponseTypeパラメータでは、応答体のオブジェクトタイプが入ってきます.下の階にあるのはHttpMessage Coverterでマッピングします.
    カスタムHttp Message Coverterで、AbstractHttp Message Coverterインターフェースを実現すればいいです.
    次のとおりです
    public class StringToJsonObjectMessageConverter extends AbstractHttpMessageConverter<JSONObject> {
         
    
        /**
         * HttpMessageConvert          
         */
        @Override
        protected boolean supports(Class<?> clazz) {
         
            return true;
        }
    
        /**
         *          
         */
        @Override
        protected JSONObject readInternal(Class<? extends JSONObject> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
         
            return null;
        }
    
        /**
         *         response
         */
        @Override
        protected void writeInternal(JSONObject jsonObject, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
         
    
        }
    }
    
    2、restTemplateのMessage Coverters属性setでカスタム変換器に入る
    @Bean
    public RestTemplate restTemplate() {
         
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();  
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        //         ,            ,    ,   0。add set     
        restTemplate.getMessageConverters().set(1,new StringToJsonObjectMessageConverter());
        return restTemplate;
    }
    
    Restit Templateのいくつかはコンバータを内蔵しています.
    StringHttp Message Coverter StringHttp Message Coverterは、HTTP要求と応答から文字列を読み出して書き込むことができる.デフォルトでは、この変換器はすべての文字メディアタイプ(text/*)をサポートしています.書き込みタイプはContent-Typeのtext/plinです.
    FormHttp Message Coverter FormHttp Message Coverterは、HTTP要求と応答からフォームデータを読み出して書き込むことができる.デフォルトでは、この変換器はメディアタイプのaplication/x-wn-form-urlencodedを読み込み、書き込みします.フォームデータは、MultiValueMapを中から読み出しまたは書き込むことができます.
    ByteArayHttpMessage Converter BytearrayHttpMessage Coverterは、HTTP要求とレスポンスから、バイト配列の読み込みと書き込みを行うことができます.デフォルトでは、この変換器はすべてのメディアタイプ(/)に対応しており、書き込みタイプはConteet-Typeのaplication/octet-streamである.supported MediaType属性とoverridingを設定することで、それをgetContentType(byte[])と上書きすることができます.
    Rest Templateを作成
    RestTemplateを作成するのは簡単で、new RestTemplate()だけが必要です.Springアーキテクチャを使用するなら、作成したRestTemplateのインスタンスをXMLまたは注釈でSpring容器に登録するだけでいいです.
    例えば:
    @Bean
    public RestTemplate restTemplate() {
         
        return new RestTemplate();
    }
    
    Restit Templateには三つのコンストラクションがあります.一つは無参、二つは参があります.以下の通りです.
    public RestTemplate() {
         }
    
    public RestTemplate(ClientHttpRequestFactory requestFactory) {
         }
    
    public RestTemplate(List<HttpMessageConverter<?>> messageConverters) {
         }
    
    複数のRest Templateのインスタンスを作成します.
    場合によっては、2つ以上の異なる構成のRestTemplateが必要です.構成ファイルに複数のRestTemplateのbeanを登録することができます.
    @Configuration
    public class MyConfiguration {
         
    
        @LoadBalanced
        @Bean
        RestTemplate loadBalanced() {
         
            return new RestTemplate();
        }
    
        @Primary
        @Bean
        RestTemplate restTemplate() {
         
            return new RestTemplate();
        }
    }
    
    注入する時は@Qualfier(「名前」)を使って注入します.そうしないとエラーが発生します.
    @Autowired
        @Qualifier("loadBalanced")
        private RestTemplate loadBalanced;
    
    Restit Templateの負荷バランス
    RertTemplateにはクライアントの負荷バランス機能がありますが、どうやってオープンしますか?簡単です.RestTemplateのbeanに@LoadBalancd注を追加すればいいです.
    例えば:
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
         
        return new RestTemplate();
    }
    
    注:Restit Templateは、スクリーンセーバが要求のURIを変更することによってサーバを指定するものであり、要求されたurlはサービスアドレスではなくサービス名を呼び出す必要があり、サービスアドレスを書くとクライアントの負荷バランスが取れなくなります.
    例:
    restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class);
    
    タイムアウト時間を設定
    タイムアウト時間を設定して、Springの最下層を直接使用して、HttpClientのHttpComponents Client HttpRequest Factoryに基づくグローバルタイムアウト時間を設定します.
      @Bean
        public RestTemplate restTemplate() {
         
            HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
            //             
            httpRequestFactory.setConnectionRequestTimeout(30 * 1000);
            //                
            httpRequestFactory.setConnectTimeout(30 * 3000);
            //         
            httpRequestFactory.setReadTimeout(30 * 3000);
            RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
            return restTemplate;
        }
    
    URIオブジェクトを作成
    RestitTemplateでHTTTPサービスを起動する時、URLはStringタイプまたはURIタイプとすることができます.次にURIオブジェクトの作成方法を見てみます.
    URIオブジェクトの無参構造方法はプライベートですので、直接呼び出すことはできません.それを使用する有参構造法が必要です.
     public URI(String str) throws URISyntaxException {
         
    
        }
    
        public URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment) throws URISyntaxException {
         
        
        }
    
    構造法を使う以外に、私達はUriComponents BuiderコンストラクタによってURIオブジェクトを生成することができます.
    例:
    UriComponents uriComponents = UriComponentsBuilder.fromUriString(
            "http://example.com/hotels/{hotel}/bookings/{booking}").build()
            .expand("42", "21")//  uri  ,     
            .encode();
    
    URI uri = uriComponents.toUri();
    
    
    Restit Template APIは使用します.
    get For Entity():Response Entityオブジェクトを返します.
    /**
     *   url: String     URI       
     *   responseType:          ,class  
     *   uriVariables: uri  ,        map
     *    :responseType   Object  
     */
    public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables){
         }
    public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables){
         }
    public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType){
         }
    
    例:
    ResponseEntity<Book> responseEntity = restTemplate.getForEntity("http://127.0.0.1:8080/getbook?bookname={1}", Book.class, "java");
    Book book = responseEntity.getBody();  //      Book  
    int statusCodeValue = responseEntity.getStatusCodeValue();  //     
    HttpHeaders headers = responseEntity.getHeaders();  //     
    
    get ForObject():指定されたObjectタイプを返します.
    public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables){
         }
    public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
    public <T> T getForObject(URI url, Class<T> responseType)
    
    例:
    Book book = restTemplate.getForObject("http://127.0.0.1:8080/getbook", Book.class);
    
    POSTメソッド
    postForEntity方法
    /**
     *   url: String     URI       
     *   request:   body,   HttpEntity  (   request header),   Object  
     *   responseType:          ,class  
     *   uriVariables: uri  ,        map
     *    :ResponseEntity Spring HTTP     ,          ,    、contentType、contentLength、response header  ,response body   
     */
    @Override
    public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)  throws RestClientException {
         
    }
    
    @Override
    public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)  throws RestClientException {
         
    }
    
    @Override
    public <T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException {
         
    }
    
    例:以下は、HttpEntityタイプの要求パラメータを使用した例です.
            //  HttpEntity            ,HttpEntity     Object       ,     HttpEntity          
            String url="http://xxx";
            //   
            HttpHeaders httpHeaders=new HttpHeaders();
            //  Content-Type(       MIME   media type)     ( POST   PUT),                 。    ,Content-Type                   。
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            //     
            httpHeaders.add("myKey","myValue");
            MultiValueMap<String,String>multiValueMap=new LinkedMultiValueMap<>();
            multiValueMap.add("name","m");
            HttpEntity httpEntity=new HttpEntity(multiValueMap,httpHeaders);
            ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
            //     
            HttpHeaders headers = stringResponseEntity.getHeaders();
            //        ,getFirst      ,get     
            String myKey = headers.getFirst("myKey");
    
            HttpStatus statusCode = stringResponseEntity.getStatusCode();
            //        response  
            String body = stringResponseEntity.getBody();
    
    注意してください.Http Entityを構成するbodyはMultiValueMapを使い、Http Entityが受け取るrequestタイプがそれです.
    MultiValueMapはMapのサブクラスであり、その1つのkeyは複数のvalueを記憶することができます.それはvalueはリストセットです.
    public interface MultiValueMap<K, V> extends Map<K, List<V>> {
         }
    
    requestは表面的に受信されたrequestは@Nullable Object requestタイプですが、追跡してみると、このrequestはHttpEntityで解析されています.コードは以下の通りです
    public HttpEntityRequestCallback(@Nullable Object requestBody, @Nullable Type responseType) {
         
    	super(responseType);
    	if (requestBody instanceof HttpEntity) {
         
    		this.requestEntity = (HttpEntity<?>) requestBody;
    	}
    	else if (requestBody != null) {
         
    		this.requestEntity = new HttpEntity<>(requestBody);
    	}
    	else {
         
    		this.requestEntity = HttpEntity.EMPTY;
    	}
    }
    
    以下は、オブジェクトを使用して要求パラメータを行う例です.
    //        request  
     restTemplate.postForEntity(url,new RequestPojo(),String.class);
    
    postForObject()
    パラメータは同じです.戻るタイプだけが違っています.直接に応答体に戻り、レスポンスタイプに変換します.
    @Override
    public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
            throws RestClientException {
         
    }
    
    @Override
    public <T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
            throws RestClientException {
         
    }
    
    @Override
    public <T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException {
         
    }
    
    例:
    //     responseType     ,        
    String result = restTemplate.postForObject(url, new RequestPojo(), String.class);
    
    exchangeの方法
    exchange()メソッドは、上記のgetForObject()、getForEntity()、postForObject()、postForEntity()などとは異なり、要求されたHTTPタイプを指定できる点にある.
        @Override
    	public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
    			@Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
    			throws RestClientException {
         
    	}
    
    	@Override
    	public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
    			@Nullable HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables)
    			throws RestClientException {
         
    	}
    
    	@Override
    	public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
    			Class<T> responseType) throws RestClientException {
         
    	}
    
    
    
    パラメータ説明:urlは要求アドレスであり、文字列であっても良いし、URIオブジェクトであっても良い.methodは要求の方法の種類であり、例えば、HttpMethod.GETはGET方法を表し、request EntityはHttp Entityタイプの要求対象を表し、レスポンスタイプは戻りの応答タイプであり、uriVarablesはURIパラメータである.
    例:
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.set("MyRequestHeader", "MyValue");
    HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
    
    HttpEntity<String> response = template.exchange(
            "http://example.com/hotels/{hotel}",
            HttpMethod.GET, requestEntity, String.class, "42");
    
    String responseHeader = response.getHeaders().getFirst("MyResponseHeader");
    String body = response.getBody();