demo2. 获取一个RESTful接口的数据
1. demo说明
本demo要点:
构建一个springboot web应用
要能从一个restful风格的接口中获取数据,并输出到console中
从接口 quoters.apps.pcfone.io/api/random 中拿数据
要用到的内容:
spring web依赖
:所以照常需要初始化一个安装了spring web依赖的脚手架RestTemplate
:通过这个springframework
中的包,来解析RESTful接口CommandLineRunner
:在springboot的控制台,自定义输出结果内容Logger
:这是一个springboot的日志对象内容,可以用它的info()
方法,把我们要自定义的信息放里面,让控制台输出
备注
:以下步骤,忽略了上面提到的,从初始化一个springboot web应用脚手架的部分,直接进入创建代码的部分
2. 搭建并运行demo
2.1 网页访问接口地址,查看数据格式,进行分析
接口地址:quoters.apps.pcfone.io/api/random
可知,接口的内容是:
{ type: "success", value: { id: 10, quote: "Really loving Spring Boot, makes stand alone Spring apps easy." } } 复制代码
这是一个两层结构的json对象,第一层包含了type和value,第二层在value内,包含了id和quote
所以按照标准的java原则,如果要将这个结果存为java的对象,那么每层都应该有一个对应java类:
Value类
:声明id
和quote
,并提供getter()
和setter()
Quote类
:声明type
和value
,提供对应的getter()
和setter()
,且value是使用的上面创建的Value类
最后在application应用执行的类中,对接口数据对象进行解析,存为Quote类型,然后以字符串形式输出
2.2 创建restfulConsuming
package
2.3 创建Value类,声明id和quote字段
@JsonIgnoreProperties annotation:
以下部分没有声明的变量,JSON解析的时候就忽略掉
package com.example.springbootDemos.restfulConsuming; 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 + ''' + '}'; } } 复制代码
2.4 创建Quote类,存储整个接口返回的内容
以下代码中,value对象是用Value类来声明的
package com.example.springbootDemos.restfulConsuming; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; /* Annotated with @JsonIgnoreProperties from the Jackson JSON processing library to indicate that any properties not bound in this type should be ignored. */ @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 + '}'; } } 复制代码
2.5 编写运行文件,让接口的结果在控制台输出
package com.example.springbootDemos.restfulConsuming; 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 restfulConsumingApplication { // A logger, to send output to the log (the console, in this example) private static final Logger log = LoggerFactory.getLogger(restfulConsumingApplication.class); public static void main(String[] args) { SpringApplication.run(restfulConsumingApplication.class, args); } // A RestTemplate, which uses the Jackson JSON processing library to process the incoming data. @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); } // A CommandLineRunner that runs the RestTemplate (and, consequently, fetches our quotation) on startup. @Bean public CommandLineRunner run(RestTemplate restTemplate) throws Exception { return args -> { // 用RestTemplate解析接口拿到的对象,并存为quote Quote quote = restTemplate.getForObject("https://quoters.apps.pcfone.io/api/random", Quote.class); // 在console中输出quote log.info(quote.toString()); // 直接通过println打印quote System.out.println("quote result: " + quote.toString()); }; } } 复制代码
2.6 运行结果
2.7 扩展:定时轮询接口,获取最新数据
介于提供样例的接口,是一个随机出quote的接口,所以如果我们想要写一个定时每3秒请求一次接口获取最新数据的方法,该怎么办呢?
常规传统解决方法
:写一个java的Runner+sleep()的方法,在线程里面进行定时请求
由于那片代码也有点多,那么在springboot脚手架下,有没有更为优雅的处理方法呢?
有!
springboot的scheduled方法!用注解来解决!
参考:springboot执行定时任务的几种方式
直接上代码:
package com.example.springbootDemos.restfulConsuming; 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.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.client.RestTemplate; @SpringBootApplication @Configuration @EnableScheduling // 开启定时任务 public class restfulConsumingApplication { // A logger, to send output to the log (the console, in this example) private static final Logger log = LoggerFactory.getLogger(restfulConsumingApplication.class); public static void main(String[] args) { SpringApplication.run(restfulConsumingApplication.class, args); } // A RestTemplate, which uses the Jackson JSON processing library to process the incoming data. @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); } RestTemplate restTemplate = new RestTemplate(); // 创建一个RESTTemplate对象 // 定时任务,用fixedRate来告诉定时器,每隔多久执行一次,也可以直接传一个cron表达式字符串,更为灵活的执行定时任务 @Scheduled(fixedRate = 3000) private void scheduledTask() { Quote quote = restTemplate.getForObject("https://quoters.apps.pcfone.io/api/random", Quote.class); log.info(quote.toString()); } } 复制代码
有几个要注意的点:
@EnableScheduling要放在类前面,不是方法前面
@Scheduled要放在方法前面,但是这个方法不能有参数
上面这段扩展代码还有个问题就是,没有使用CommandLineRunner在一开始就执行一次,且没有设置定时任务取数据异常的抛出(以后具体研究annotation的时候再说吧~)
作者:阿申申Cindy
链接:https://juejin.cn/post/7031480200395390983