Consuming a RESTful Web Service
這份教程教你如果創一個使用RESTFul風格的WebService應用。
What you’ll build
你會創建一個怎樣的APP呢?它會用Spring’s RestTemplate去重現下面地址所能實現的結果
http://gturnquist-quoters.cfapps.io/api/random
(就是返回一個隨機ID的JSON類型的JAVA類嘛╮(╯_╰)╭)
How to complete this guide
跟其他的Spring教程差不多,你可以從一步一步搭建SpringBoot環境開始,或者可以跳過這些基礎的配置(如果比較熟練了的話,直接在idea里用Spring initializer或者spring.ios上下載)。最終你能得到一份可以直接書寫業務的代碼。
Fetch a REST resource
當項目全部配置完畢,你可以創造出一個簡單的使用RESTFul service的app。
一個RESTFul service已經在這個地址上演示了:http://gturnquist-quoters.cfapps.io/api/random。它能隨機給出一個Spring Boot的名言(點點看就知道了),用JSON形式返回。
如果你訪問這個地址的話,你會收到這樣的一個JSON對象比如:
{
type: "success",
value: {
id: 10,
quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
}
}
挺簡單的,不過客戶直接獲取到這樣的數據。。。似乎並沒啥屌用。
這類的返回值一般都是用程序去訪問的,這類數據就像MVC中的M,然后給出一個V用於渲染,再返回。
一般而言,這類的REST web service都是用程序去訪問的,Spring在這方面(程序訪問web接口)提供了RestTemplate去方便開發。RestTemplate讓與這些RESTFul service的訪問只用一句代碼,而且能自動轉換類型。
首先,創建一個entity類。
src/main/java/hello/Quote.java
package hello;
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里來的,這個注解用於表示忽略空字段,也就是說,在class轉JSON的時候,如果有空字段,空字段不會出現在JSON中。
為了能讓數據正確轉換,你需要讓json里的變量名跟class里的變量名能對的上,不然你也可以加個@JsonProperty手動去設置名字。
除了上面的Quota類,還需要創建一個Value類(Quota的內部類)
src/main/java/hello/Value.java
package hello;
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 + '\'' +
'}';
}
}
規則跟上面的Quota一樣(屬性名得對上)
Make the application executable
盡管可以像傳統項目一樣打成war包放webapp里,更直接的方式是像下面這樣打包(gradle里面的bootJar),它能把項目打成一個單個的jar,通過main函數啟動,其內置了tomcat。
你可以直接在Application類里用RestTemplate獲取之前那個URL里的數據:
src/main/java/hello/Application.java
package hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.client.RestTemplate;
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String args[]) {
RestTemplate restTemplate = new RestTemplate();
Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
}
}
因為Jackson JSON導過包了,RestTemplate會用它去解析URL下的String/JSON對象,轉換成對應的類。至此,剛剛解析到的Quote類里的內容會被打印到控制台上。
到這里你已經用RestTemplate去發起一個HTTP的GET請求了,不過RestTemplate同樣支持POST,PUT,DELETE請求。
Managing the Application Lifecycle with Spring Boot
到目前為止我們還沒在我們的應用里用到Spring Boot,不過這么做也有點好處,而且也不難。
接下來用Spring Boot的形式改寫一個主類吧。
src/main/java/hello/Application.java
package hello;
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 Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
}
}
RestTemplateBuilder是被Spring啟動時注入的,如果你通過它去創建一個RestTemplate,那這個RestTemplate就能接受到所有相應的配置(在properties配置的關於RestTemplate的)。