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的)。