本章带你创建一个应用,这个应用调用一个RESTful网络服务。
本文目标
用Spring Boot构建一个应用,使用RestTemplate从https://gturnquist-quoters.cfapps.io/api/random上面取回一段随机的Spring Boot引语。
你需要
- 15分钟左右
- IntelliJ IDEA
- JDK 1.8+
- Maven 3.2+
用Spring Initializr生成项目代码
对于所有的Spring应用,你都可以使用Spring Initializr生成基本的项目代码。Initializr提供了一个快速的方式去引入所有你需要的依赖,并且为你做了很多设置。当前例子只需要Spring Web依赖。具体设置如下图:
如上图所示,我们选择了Maven作为编译工具。你也可以选择Gradle来进行编译。然后我们分别把Group和Artifact设置为“com.hansy”和“consuming-test”。
生成的pom.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hansy</groupId>
<artifactId>consuming-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consuming-test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
编译配置文件之所以这么简单,是因为spring-boot-starter-web依赖包含了一个Web应用所需要的所有东西,比如处理JSON所需要的Jackson库。
调用一个REST资源
项目配置好了,我们可以创建一个简单应用,来调用一个RESTful服务。
一个RESTful服务已经运行在https://gturnquist-quoters.cfapps.io/api/random。它以JSON格式返回一条关于Spring Boot随机的引语。
如果你通过浏览器或者curl命令访问该网址,你会收到一个JSON字符串,类似于下面这样:
{
type: "success",
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"
}
}
通过浏览器或者curl命令获取数据虽然很简单,但是不够有用。
通过编程调用REST网络服务的方式更有用。Spring提供了一个便利的模板类,叫做RestTemplate,可以帮助你完成服务的调用。RestTemplate使大部分的RESTful服务的调用只用一行代码就行实现。并且可以把数据绑定到自定义实体类。
首先,你需要创建一个实体类来包含你需要的数据。代码如下:
package com.hansy.consumingtest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {
private String type;
private Value value;
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、setter方法。该类添加了Jackson JSON处理库的@JsonIgnoreProperties注解,该注解会使实体类中不存在的字段被Jackson忽略。
为了直接绑定数据到自定义的实体类,你需要制定类的字段名和API返回的JSON字符串中key值完全一样。假如你的字段名和JSON字符串的key值不匹配,你可以使用@JsonProperty注解来制定真实的key值。(本例中字段名和key值完全匹配,不需要设置@JsonProperty)
我们还需要一个额外的类,来嵌入内部引语。代码如下:
package com.hansy.consumingtest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {
private String type;
private Value value;
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 +
'}';
}
}
完成应用
Initalizr生成了一个包含main()方法的入口类。代码如下:
package com.hansy.consumingtest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConsumingTestApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumingTestApplication.class, args);
}
}
现在我们需要添加一些东西到ConsumingTestApplication类,利用RESTful服务来显示Spring Boot引语。你需要添加:
- logger,发送输入到log(本例中是控制台)
- RestTemplate,使用 Jackson JSON处理库来处理收到的数据。
- CommandLineRunner,程序开始时运行RestTemplate(取到我们的Spring Boot引语)。
最终版的ConsumingRestApplication如下所示:
package com.hansy.consumingtest;
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 ConsumingTestApplication {
private static final Logger logger = LoggerFactory.getLogger(ConsumingTestApplication.class);
public static void main(String[] args) {
SpringApplication.run(ConsumingTestApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner commandLineRunner(RestTemplate restTemplate) {
return args -> {
Quote quote = restTemplate.getForObject("https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
logger.info(quote.toString());
};
}
}
运行应用
你可以在控制台看到类似于下面的输出,但是有一个不同的Spring Boot引语:
2020-07-11 16:29:08.024 INFO 21044 --- [ main] c.h.c.ConsumingTestApplication : Quote{type='success', value=Value{id=10, quote='Really loving Spring Boot, makes stand alone Spring apps easy.'}}
小结
你已经用Spring Boot开发了一个简单的REST客户端。