[原创]3. RESTful Web服务之间通信

学习如何使用Spring的RestTemplate检索网页数据。

实现效果:

创建RESTful Web服务获取并处理另外一个RESTful Web服务提供的数据。
使用Spring的RestTemplate获取
https://gturnquist-quoters.cfapps.io/api/random
这个API返回的随机值,并处理.

项目结构
└── src

    └── main

        └── java

            └── hello
pom.xml


    4.0.0

    org.springframework
    gs-consuming-rest
    0.1.0

    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.4.RELEASE
    

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework
            spring-web
        
        
            com.fasterxml.jackson.core
            jackson-databind
        
    


    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


1.获取REST资源

已在https://gturnquist-quoters.cfapps.io/api/random开启了一个RESTful服务。 它随机获取 一个Spring Boot的引用并返回JSON文本。
通过Web浏览器或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能和大多数单行请求RESTful服务交互。 还可以将数据绑定到自定义类型。
首先创建一个实体类,包含type, value.其中value也是一个josn,包含id和quote.
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方法。使用Jackson JSON类库中的@JsonIgnoreProperties进行注解,表示应忽略此类中未绑定的任何属性。
为了直接将数据绑定到自定义类型,需要指定API返回的JSON中的key完全相同的变量名称。如果JSON 中的变量名称和key不匹配,则需要使用@JsonProperty注解指定JSON文本的key。
创建第二个实体类对应value

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 + '\'' +
                '}';
    }
}

执行程序

修改Application 类,用RestTemplate 从上面的Spring boot 引用服务抓取 数据
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("https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
        log.info(quote.toString());
    }

}

由于 Jackson JSON 库在类路径中,RestTemplate 将使用它(通过消息转换器)将传入的JSON 数据转换为Quote对象。 Quote对象的内容将打印到控制台。
除了HTTP GET请求。RestTemplate还支持其他HTTP动作,如POST,PUT和DELETE。

使用Spring Boot管理应用程序生命周期

到目前为止,还没有在应用程序中使用Spring Boot,这样做有一些优点,也不难做到。其中一个优点是可以让Spring Boot管理RestTemplate中的消息转换器,以便以注解的方式轻松添加自定义内容。为此,在主类上使用@SpringBootApplication并转换main方法 启动,就像在任何Spring Boot应用程序中一样。最后,run方法回调RestTemplate返回CommandLineRunner类型的值,这样就由Spring Boot管理其生命周期:
修改Application类
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(
                    "https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
            log.info(quote.toString());
        };
    }
}

RestTemplateBuilder由Spring注入,使用它来创建RestTemplate, Spring Boot会自动使用消息转换器和请求工厂的所有自动配置。 还可将RestTemplate提取到@Bean中,以便更容易测试(可以通过这种方式更容易地进行模拟测试)。

建立一个可执行的 JAR

利用maven打包war或者jar运行,这里不做介绍.
java -jar target/gs-consuming-rest-0.1.0.jar

测试

运行后将会出现类似下方的日志输出:

2015-09-23 14:22:26.415  INFO 23613 --- [main] hello.Application  : Quote{type='success', value=Value{id=12, quote='@springboot with @springframework is pure productivity! Who said in #java one has to write double the code than in other langs? #newFavLib'}}

如果出现如下错误:
Could not extract response: no suitable HttpMessageConverter found for response type [class hello.Quote]
可能由于你的网络环境不能访问
https://gturnquist-quoters.cfapps.io/api/random

你可能感兴趣的:([原创]3. RESTful Web服务之间通信)