阅读 217

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

image.png

可知,接口的内容是:

{    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类:声明idquote,并提供getter()setter()

  • Quote类:声明typevalue,提供对应的getter()setter(),且value是使用的上面创建的Value类

最后在application应用执行的类中,对接口数据对象进行解析,存为Quote类型,然后以字符串形式输出

2.2 创建restfulConsumingpackage

image.png

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 运行结果

image.png

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


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐