Spring Boot(3)--Consuming a RESTful Web Service 就是取得一個RESTful形式的Web服務 CommandLineRunner未完全理解

springboot的總官方學習文檔

本次本章對應的官方文檔

目標

本指南將引導您完成創建使用RESTful Web服務的應用程序的過程,官網指導用的是Consuming,我感覺這個意思就是說,我們的搭建的服務器看做一個客戶,對另一個服務器發送一個請求,消耗了另一個服務器的一個RESTful形式的Web服務。

我們將使用Spring的RestTemplate 來構建一個應用,這個應用可以從 https://gturnquist-quoters.cfapps.io/api/random取回一個隨機的Spring boot 的 quotation ,這個quotation 我有點懵,這啥意思,後來感覺翻譯成語錄更好,因爲返回的內容都是誇Spring的,如下圖
在這裏插入圖片描述
還是老樣子,https://github.com/spring-guides/gs-consuming-rest.git github直接下載下來,Eclipse打開
在這裏插入圖片描述
插入 file->import

在這裏插入圖片描述

獲取REST資源

完成項目設置後,您可以創建一個使用RESTful服務的簡單應用程序。

RESTful服務已設置在了 https://gturnquist-quoters.cfapps.io/api/random。本次設計的簡單應用程序 隨機獲取有關Spring Boot的語錄,並將其作爲JSON文檔返回。
如果您通過網絡瀏覽器或curl請求該URL,則會收到看起來像這樣的JSON文檔

{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}

通過瀏覽器或curl獲取時,這很容易,但並不是很有用。

使用REST Web服務的一種更有用的方法是編程方式。爲了幫助您完成該任務,Spring提供了一個名爲的便捷模板類RestTemplate。

下面兩句不太好理解官方指南是RestTemplate makes interacting with most RESTful services a one-line incantation. And it can even bind that data to custom domain types.
RestTemplate 這個類讓與大多數RESTful 形式服務 的交互成爲了一個一行的咒語(可以的,這個B給你120,20分附加的),它甚至可以將數據綁定到自定義域類型(這個不太懂)

首先,您需要創建一個域類來包含你所需的數據,就是上面那個有type value兩個屬性的。以下清單顯示了Quote該類,您可以將其用作域類

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {

  private String type;
  private Value value;

  public Quote() {
  }

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }

  public Value getValue() {
    return value;
  }

  public void setValue(Value value) {
    this.value = value;
  }

  @Override
  public String toString() {
    return "Quote{" +
        "type='" + type + '\'' +
        ", value=" + value +
        '}';
  }
}

這個簡單的Java類具有一些屬性和與這些屬性相匹配的Getter方法。它@JsonIgnoreProperties 這個註釋,用在Jackson JSON處理庫中,來指示應忽略此類型中未綁定的任何屬性,上面是未綁定的,就是我們這裏只綁定了type 和value兩個屬性,其他的屬性再JSON處理的時候就直接忽略了。

補充一下:本文代碼使用了@JsonIgnoreProperties(ignoreUnknown = true),我們直接查看JsonIgnoreProperties的文檔就會發現這句話
// To ignore any unknown properties in JSON input without exception:
//爲了忽略JSON輸入的任意未知的屬性而不會報錯
@JsonIgnoreProperties(ignoreUnknown=true)
但是文檔中的另一句沒太理解
// to prevent specified fields from being serialized or deserialized
// (i.e. not include in JSON output; or being set even if they were included)
@JsonIgnoreProperties({ “internalId”, “secretKey” })

然後看到這個博客Spring Boot程序中@JsonIgnoreProperties與@JsonIgnore基本使用

  • @JsonIgnore註解用來忽略某些字段,可以用在變量或者Getter方法上,用在Setter方法時,和變量效果一樣。這個註解一般用在我們要忽略的字段上。

  • @JsonIgnoreProperties(ignoreUnknown = true),將這個註解寫在類上之後,就會忽略類中不存在的字段。這個註解還可以指定要忽略的字段,例如@JsonIgnoreProperties({ “password”, “secretKey” })

  • @JsonFormat可以幫我們完成格式轉換。例如對於Date類型字段,如果不適用JsonFormat默認在rest返回的是long,如果我們使用@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”),就返回"2018-11-16 22:58:15"

額,轉的又多了,看到好的文章總想多複製點。。。。

要將數據直接綁定到自定義類型,您需要指定變量名稱,使其與從API返回的JSON文檔中的鍵完全相同。如果您的變量名稱和JSON文檔中的密鑰不匹配,則可以使用@JsonProperty批註指定JSON文檔的確切密鑰。(此示例將每個變量名稱與一個JSON鍵匹配,因此在這裏您不需要該註釋。)

但是由於返回的JSON其實是可以看成兩層嵌套,所以還需要一個附加的類來表示內部的value屬性。該Value級滿足了這一需求

{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}

代碼

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Value {

  private Long id;
  private String quote;

  public Value() {
  }

  public Long getId() {
    return this.id;
  }

  public String getQuote() {
    return this.quote;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public void setQuote(String quote) {
    this.quote = quote;
  }

  @Override
  public String toString() {
    return "Value{" +
        "id=" + id +
        ", quote='" + quote + '\'' +
        '}';
  }
}

完成申請

現在,您需要向ConsumingRestApplication 這個包含Main函數的類中添加一些其他內容,以使其顯示來自我們RESTful源的報價。您需要添加:

  • 記錄器,用於將得到的返回數據發送到日誌(在此示例中爲控制檯)。
  • A RestTemplate,它使用Jackson JSON處理庫來處理傳入的數據。
  • 在啓動時CommandLineRunner運行RestTemplate(因此獲取我們的語錄)。

代碼如下:

package com.example.consumingrest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsumingRestApplication {

	private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);

	public static void main(String[] args) {
		SpringApplication.run(ConsumingRestApplication.class, args);
	}

	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build();
	}

	@Bean
	public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
		return args -> {
			Quote quote = restTemplate.getForObject(
					"https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
			log.info(quote.toString());
		};
	}
}

理解補充:

RestTemplate是Spring中對HttpClient的再次封裝,簡化了發起HTTP請求以及處理響應的過程,抽象層級更高,減少消費者的模板代碼,使冗餘代碼更少。比如建立連接,構造請求頭和請求體,然後根據響應,解析響應信息,最後關閉連接。

在項目中,當我們需要遠程調用一個HTTP接口時,我們經常會用到RestTemplate這個類。這個類是Spring框架提供的一個工具類。

RestTemplate是一個同步的Rest API客戶端。下面我們就來介紹下RestTemplate的常用功能。
下面代碼就是使用RestTemplateBuilder配置RestTemplate,我們如果想使用RestTemplate,必須配置一下,更多關於RestTemplate的用法

	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build(); 
		//Build a new {@link RestTemplate} instance and configure it using this builder.
	}

然後什麼是Bean?
SpringBean是被實例的,組裝的及被Spring容器管理的Java對象

RestTemplate.getForObject方法
Retrieve a representation by doing a GET on the specified URL.The response (if any) is converted and returned.
通過對指定的URL進行一個GET請求 來得到一個返回,並且這個返回可以被轉換爲指定的形式
參數:
Parameters:
url:the URLresponse
Type:the type of the return value
總結就是:
我們平時會將一個對象轉換爲json格式發給前端,這裏則是從瀏覽器獲取了一個json並轉換爲對象,果然是consume

理解CommandLineRunner

Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined with in the same application context and can be ordered using the Orderedinterface or @Order annotation.
CommandLineRunner首先本質是一個接口,用於指示應當運行的 包含在SpringApplication中 bean。可以在同一應用程序上下文中用定義多個CommandLineRunner bean,並且可以使用Orderedinterface或@Order註釋進行排序。

使用spring boot管理應用的生命週期,@Bean Spring可以從當前方法獲取一個bean
這裏使用了一個args->的lambda表達式,並且之後參數中沒有args

Lambda是什麼?
Lambda是一個匿名函數,我們可以把Lambda表達式理解爲是一段可以傳遞的代碼(將代碼像數據一樣傳遞)。可以寫出更簡潔、更靈活的代碼。作爲一種更緊湊的代碼風格,使java的語言表達能力得到了提升
Lambda只需要一個參數時,參數的小括號可以省略

CommandLineRunner是一個接口(函數式接口),我們返回的是一個函數,這個函數有一個參數args,並且這個args是一個String [] 因爲
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章