Spring Boot(3)--Consuming a RESTful Web Service 就是取得一个RESTful形式的Web服务 CommandLineRunner未完全理解

springboot的总官方学习文档

本次本章对应的官方文档

目标

本指南将引导您完成创建使用RESTful Web服务的应用程序的过程,官网指导用的是Consuming,我感觉这个意思就是说,我们的搭建的服务器看做一个客户,对另一个服务器发送一个请求,消耗了另一个服务器的一个RESTful形式的Web服务。

我们将使用Spring的RestTemplate 来构建一个应用,这个应用可以从 https://gturnquist-quoters.cfapps.io/api/random取回一个随机的Spring boot 的 quotation ,这个quotation 我有点懵,这啥意思,后来感觉翻译成语录更好,因为返回的内容都是夸Spring的,如下图
在这里插入图片描述
还是老样子,https://github.com/spring-guides/gs-consuming-rest.git github直接下载下来,Eclipse打开
在这里插入图片描述
插入 file->import

在这里插入图片描述

获取REST资源

完成项目设置后,您可以创建一个使用RESTful服务的简单应用程序。

RESTful服务已设置在了 https://gturnquist-quoters.cfapps.io/api/random。本次设计的简单应用程序 随机获取有关Spring Boot的语录,并将其作为JSON文档返回。
如果您通过网络浏览器或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 makes interacting with most RESTful services a one-line incantation. And it can even bind that data to custom domain types.
RestTemplate 这个类让与大多数RESTful 形式服务 的交互成为了一个一行的咒语(可以的,这个B给你120,20分附加的),它甚至可以将数据绑定到自定义域类型(这个不太懂)

首先,您需要创建一个域类来包含你所需的数据,就是上面那个有type value两个属性的。以下清单显示了Quote该类,您可以将其用作域类

package com.example.consumingrest;

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处理库中,来指示应忽略此类型中未绑定的任何属性,上面是未绑定的,就是我们这里只绑定了type 和value两个属性,其他的属性再JSON处理的时候就直接忽略了。

补充一下:本文代码使用了@JsonIgnoreProperties(ignoreUnknown = true),我们直接查看JsonIgnoreProperties的文档就会发现这句话
// To ignore any unknown properties in JSON input without exception:
//为了忽略JSON输入的任意未知的属性而不会报错
@JsonIgnoreProperties(ignoreUnknown=true)
但是文档中的另一句没太理解
// to prevent specified fields from being serialized or deserialized
// (i.e. not include in JSON output; or being set even if they were included)
@JsonIgnoreProperties({ “internalId”, “secretKey” })

然后看到这个博客Spring Boot程序中@JsonIgnoreProperties与@JsonIgnore基本使用

  • @JsonIgnore注解用来忽略某些字段,可以用在变量或者Getter方法上,用在Setter方法时,和变量效果一样。这个注解一般用在我们要忽略的字段上。

  • @JsonIgnoreProperties(ignoreUnknown = true),将这个注解写在类上之后,就会忽略类中不存在的字段。这个注解还可以指定要忽略的字段,例如@JsonIgnoreProperties({ “password”, “secretKey” })

  • @JsonFormat可以帮我们完成格式转换。例如对于Date类型字段,如果不适用JsonFormat默认在rest返回的是long,如果我们使用@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”),就返回"2018-11-16 22:58:15"

额,转的又多了,看到好的文章总想多复制点。。。。

要将数据直接绑定到自定义类型,您需要指定变量名称,使其与从API返回的JSON文档中的键完全相同。如果您的变量名称和JSON文档中的密钥不匹配,则可以使用@JsonProperty批注指定JSON文档的确切密钥。(此示例将每个变量名称与一个JSON键匹配,因此在这里您不需要该注释。)

但是由于返回的JSON其实是可以看成两层嵌套,所以还需要一个附加的类来表示内部的value属性。该Value级满足了这一需求

{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}

代码

package com.example.consumingrest;

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

完成申请

现在,您需要向ConsumingRestApplication 这个包含Main函数的类中添加一些其他内容,以使其显示来自我们RESTful源的报价。您需要添加:

  • 记录器,用于将得到的返回数据发送到日志(在此示例中为控制台)。
  • A RestTemplate,它使用Jackson JSON处理库来处理传入的数据。
  • 在启动时CommandLineRunner运行RestTemplate(因此获取我们的语录)。

代码如下:

package com.example.consumingrest;

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 ConsumingRestApplication {

	private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);

	public static void main(String[] args) {
		SpringApplication.run(ConsumingRestApplication.class, args);
	}

	@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());
		};
	}
}

理解补充:

RestTemplate是Spring中对HttpClient的再次封装,简化了发起HTTP请求以及处理响应的过程,抽象层级更高,减少消费者的模板代码,使冗余代码更少。比如建立连接,构造请求头和请求体,然后根据响应,解析响应信息,最后关闭连接。

在项目中,当我们需要远程调用一个HTTP接口时,我们经常会用到RestTemplate这个类。这个类是Spring框架提供的一个工具类。

RestTemplate是一个同步的Rest API客户端。下面我们就来介绍下RestTemplate的常用功能。
下面代码就是使用RestTemplateBuilder配置RestTemplate,我们如果想使用RestTemplate,必须配置一下,更多关于RestTemplate的用法

	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build(); 
		//Build a new {@link RestTemplate} instance and configure it using this builder.
	}

然后什么是Bean?
SpringBean是被实例的,组装的及被Spring容器管理的Java对象

RestTemplate.getForObject方法
Retrieve a representation by doing a GET on the specified URL.The response (if any) is converted and returned.
通过对指定的URL进行一个GET请求 来得到一个返回,并且这个返回可以被转换为指定的形式
参数:
Parameters:
url:the URLresponse
Type:the type of the return value
总结就是:
我们平时会将一个对象转换为json格式发给前端,这里则是从浏览器获取了一个json并转换为对象,果然是consume

理解CommandLineRunner

Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined with in the same application context and can be ordered using the Orderedinterface or @Order annotation.
CommandLineRunner首先本质是一个接口,用于指示应当运行的 包含在SpringApplication中 bean。可以在同一应用程序上下文中用定义多个CommandLineRunner bean,并且可以使用Orderedinterface或@Order注释进行排序。

使用spring boot管理应用的生命周期,@Bean Spring可以从当前方法获取一个bean
这里使用了一个args->的lambda表达式,并且之后参数中没有args

Lambda是什么?
Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使java的语言表达能力得到了提升
Lambda只需要一个参数时,参数的小括号可以省略

CommandLineRunner是一个接口(函数式接口),我们返回的是一个函数,这个函数有一个参数args,并且这个args是一个String [] 因为
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值