本文为实战SpringCloud响应式微服务系列教程第八章,讲解构建响应式RESTful服务。建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末。

1.使用springboot2.1.4构建RESTful风格服务

Springboot的设计是用来简化Spring应用程序的初始搭建和开发过程,为了实现这种简化效果,Springboot继承了众多第三方库,并大量使用约定优于配置的设计理念,通过特定的方式使得开发人员不再需要定义繁杂而且多余的配置内容。

1.1基于Springboot的第一个RESTful服务

微服务架构推崇采用RESTful风格实现服务之间的交互。关于RESTful,很多开发人员在知识体系上的一些误解和不足。我们先对RESTful风格做一个简单的介绍,然后详细阐述使用SpringBoot构建单个RESTful服务的过程。

(1)RESTful风格简介

REST提出了一组建构约束条件和原则,满足这些约束条件和原则的设计风格就是RESTful。

现实世界中的事物都可以被认为一种资源,我们可以根据这些约束条件和原则设计以资源为中心的服务。REST中最重要的一条原则就是客户端和服务器之间的交互无状态性。

从客户端到服务器的每个请求都必须包含理解该请求所必需的信息,无状态请求可以由任何可用服务实现响应,十分适合微服务架构的运行环境。所以RESTful代表的实际上是一种风格,而不是一种设计和架构模式,更不是一种具体的技术体系。

关于RESTful另一个比较容易忽视的核心概念是HATEOAS(Hypermedia as the Engine of Application State,基于超媒体的应用状态引擎)。要解释HATEOAS的概念,先要解释什么是超媒体。

我们已经知道什么是超链接以及什么是超文本,其中超文本的特有优势是拥有超链接。如果把超链接映入到多媒体中,就得到了超媒体。因此关键要素还是超链接。使用过超媒体作为应用引擎状态,意思就是应用引擎的状态变更由客户端访问不同的超媒体资源来驱动。

使用HATEOAS表现服务请求响应的风格如下,可以看到这里多了_links属性,其中有一个self.href链接指向当前user资源。

GET http://api.example.com/users/tianyalan
Content-type:application/json
{
_links:{
self:{
href:"/users/tianyalan"
}
}
"id":"tianyalan",
"name":"tianyalan",
"email":"tianyalan@email.com"
}

HATEOAS在spring boot和spring cloud中应用也非常广泛,例如springboot提供了应用监控组件Actuator,通过Actuator可以获取springboot应用程序当前的运行状态,我们将在后续章节中详细介绍Actuator组件。

Actuator组件对外暴露的也是一些http端点,访问这些端点返回的数据跟常见的RESTful风格有所不同,这就是HATEOAS风格,所以可以参考相关资料进一步了解。

(2)引入spring-boot-starter-web工程

spring boot提供了一系列starter工程来简化各组件之间的依赖关系。

例如在springboot中开发基于RESTful风格的端点时,通常会引入spring-boot-starter-web这个工程,而打开这个工程会发现里面实际上只定义了如下所示的一些pom依赖,其中包括所有我们能够预见到的组件,例如非常经典的spring-web,spring-webmvc组件,可以看到spring-boot-starter-web还是基于这两个组件构建web请求响应流程的。

另外还包含了基于JSON序列化和反序列化的jackson-databind组件,以及启动内置tomcat服务器的spring-boot-starter-tomcat组件。

  • org.springframework.boot:spring-boot-starter
  • org.springframework.boot:spring-boot-starter-tomcat
  • org.springframework.boot:spring-boot-starter-validation
  • org.springframework.boot:spring-web
  • org.springframework.boot:spring-webmvc
  • org.fasterxml.jackson.core:jackson-databind

引入spring-boot-starter-web就像引入一个普通的maven依赖一样,代码如下:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

一旦spring-boot-starter-web组件引入完毕,我们就可以充分利用springboot的自动装配机制开发单个服务。

(3)Application类

使用springboot的首要条件是构建一个Application启动类。代码如下:

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

结构比较固化。

显然以上代码关键的是@SpringBootApplication注解。springboot使用@SpringBootApplication注解来告诉spring容器具备该注解的类是整个spring容器中所有javaBean对象的入口,而具备该注解的类在springboot中就是Application类。

在上面代码中,SoulApplication类就是整个容器的Application类。

@SpringBootApplication注解在指定Application类的同时,还会自动扫描与当前类同级以及子包下的@Component、@Service、@Repository、@Controller、@Entity等注解,并把这些注解对应的类转换为Bean对象全部加载到Spring容器中管理起来。

@SpringBootApplication注解的定义如下,我们可以看到该注解实际上由三个注解组合而成,分别是@Configuration、@EnableAutoConfigguration和@ComponentScan。

@Target(ElementType.TYPE)
@Retenation(RetentionPolicy.PUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfigguration
@ComponentScan
public @interface SpringBootApplication

在Spring 中@Configuration比较常见,提供javaConfig配置类实现。而@ComponentScan则扫描@Component等注解,帮相关的javaBean定义批量加载到IOC容器中。@EnableAutoConfigguration最终会使用JDK提供的SPI机制来实现类的动态加载。

关于@EnableAutoConfigguration注解更多的可以参考相关的资料。

我们还注意到在上面的代码示例中包含一个main函数并执行了ApplicationContext对象,我们可以根据需求对该ApplicationContext对象做响应处理。

(4)Controller类

Application类提供了Springboot程序的入口,相当于应用程序拥有了最基本的骨架。接下来我们就可以添加各种业务相关的访问入口,表现在RESTful风格上也就是一系列的Controller类所代表的的HTTP端点。

这里的Controller和springMvc的Controller在概念上是一致的。最简单的Controller如下:

@RestController
public class HelloController{
@GetMapping("/")
public String index(){
return "Hello Spring Boot";
}
}

以上代码包含了@RestController和@GetMapping("/")两个注解。我们知道在springMvc中包含了@Controller注解用来表示当前类是一个servlet。

而@RestController继承了@Controller,它告诉Springboot这是一个基于RESTful风格的HTTP端点,并会自动使用JSON实现HTTP请求和响应的序列化和反序列化操作。至于@GetMapper类似@RequestMapping,指定请求方式为GET。这里不做多余介绍。

以下代码展示了一个典型的Controller,在Controller中通过静态的业务代码完成了根据商品编号,获取商品信息的业务流程。

这里用到了两层Mapping注解,在服务层级定义了服务的版本和路径,分别为v1和products;而在操作级别有定义了HTTP请求方法的具体路径及参数信息。

@RestController
@RequestMapping("/v1/products")
public class Productontroller{
@GetMapping("/{productCode}")
public Product getProduct(@PathVariable String productCode){
Product product = new Product();
product .setId(1L);
product .setPrice(100F);
product .setProductCode("product001");
product .setProductName("product");
return product;
}
}

系列章节目录

实战SpringCloud响应式微服务系列教程(第一章)

实战SpringCloud响应式微服务系列教程(第二章)

实战SpringCloud响应式微服务系列教程(第三章)

实战SpringCloud响应式微服务系列教程(第四章)

实战SpringCloud响应式微服务系列教程(第五章)

实战SpringCloud响应式微服务系列教程(第六章)

实战SpringCloud响应式微服务系列教程(第七章)

实战SpringCloud响应式微服务系列教程(第八章)构建响应式RESTful服务的更多相关文章

  1. 实战SpringCloud响应式微服务系列教程(第二章)

    接上一篇:实战SpringCloud响应式微服务系列教程(第一章) 1.1.2背压 背压是响应式编程的核心概念,这一节也是我们了解响应式编程的重点. 1.背压的机制 在生产者/消费者模型中,我们意识到 ...

  2. 实战SpringCloud响应式微服务系列教程(第三章)

    接着之前的: 实战SpringCloud响应式微服务系列教程(第一章) 实战SpringCloud响应式微服务系列教程(第二章) 1.1.3Reactor框架 响应式编程是一种编程模型,本节将介绍这种 ...

  3. 实战SpringCloud响应式微服务系列教程(第四章)

    接上一篇: 实战SpringCloud响应式微服务系列教程(第一章) 实战SpringCloud响应式微服务系列教程(第二章) 实战SpringCloud响应式微服务系列教程(第三章) 1.1.4 引 ...

  4. 实战SpringCloud响应式微服务系列教程(第六章)

    本章节介绍:Flux和Mono操作符 和其他主流的响应式编程一样,Reactor框架的设计目标也是为了简化相应式流的使用方法.为此Reactor框架提供了大量操作符用于操作Flux和Mono对象. 本 ...

  5. 实战SpringCloud响应式微服务系列教程(第七章)

    本章节继续介绍:Flux和Mono操作符(二) 1.条件操作符 Reactor中常用的条件操作符有defaultIfRmpty.skipUntil.skipWhile.takeUntil和takeWh ...

  6. 实战SpringCloud响应式微服务系列教程(第九章)使用Spring WebFlux构建响应式RESTful服务

    本文为实战SpringCloud响应式微服务系列教程第九章,讲解使用Spring WebFlux构建响应式RESTful服务.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 从本节开始我们 ...

  7. 实战SpringCloud响应式微服务系列教程(第十章)响应式RESTful服务完整代码示例

    本文为实战SpringCloud响应式微服务系列教程第十章,本章给出响应式RESTful服务完整代码示例.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 1.搭建响应式RESTful服务. ...

  8. 实战SpringCloud响应式微服务系列教程(第一章)

    前言 在当今互联网飞速发展的时代,业务需求不断的更新和产品的迭代给系统开发过程和编程模式也带来巨大挑战,Spring Cloud微服务也随之应用而生,从springboot1.x到springboot ...

  9. Spring WebFlux 教程:如何构建反应式 Web 应用程序

    Spring WebFlux 教程:如何构建反应式 Web 应用程序 反应式系统提供了我们在高数据流世界中所需的无与伦比的响应能力和可扩展性.然而,反应式系统需要经过专门培训的工具和开发人员来实现这些 ...

随机推荐

  1. [DE] How to learn Big Data

    打开一瞧:50G的文件! emptystacks jobstacks jobtickets stackrequests worker 大数据加数据分析,需要以python+scikit,sql作为基础 ...

  2. .Net Core 3.0 gRPC部署问题解决

    前言 .Net Core3.0终于如约而至的来了.在3.0中增加了许多东西.也有了许多的变化.今天我们看的就是在3.0中使用gRPC并遇到的问题.gRPC现在可以非常方便简洁的在.Net Core中使 ...

  3. .Net Core中间件和过滤器实现错误日志记录

    1.中间件的概念 ASP.NET Core的处理流程是一个管道,中间件是组装到应用程序管道中用来处理请求和响应的组件. 每个中间件可以: 选择是否将请求传递给管道中的下一个组件. 可以在调用管道中的下 ...

  4. Flask基础(14)-->自定义过滤器

    Flask基础(13)-->自定义过滤器 什么是过滤器? 过滤器的本质就是函数.有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化.运算等等,而在模板中是不能直接调用 P ...

  5. 【ADO.NET基础知识】SqlConnection、command、DataSet 、DataTable、dataAdapter

    1.使用Connection连接数据库的步骤: (1).添加命名空间 System.Data.SqlClient(注意:初学者经常会忘记) (2)定义连接字符串.连接SQL Server 数据库时: ...

  6. 一个网站完整的SEO优化方案,方法,怎么做seo优化?

    SEO优化主要分为站内优化,站外优化.如果非得说一套完整的SEO优化方案,那就是需要4名专业人员:前端人员,内容编辑,网络推广人员,和数据分析人员.那以下就详细介绍这四个岗位各自负责的工作有哪些: 一 ...

  7. 死磕 java线程系列之自己动手写一个线程池

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. (手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写 ...

  8. 如何决定使用 HashMap 还是 TreeMap?

    问:如何决定使用 HashMap 还是 TreeMap? 介绍 TreeMap<K,V>的Key值是要求实现java.lang.Comparable,所以迭代的时候TreeMap默认是按照 ...

  9. Docker学习1-CentOS 7安装Docker

    前言 docker 是一个开源的应用容器引擎,基于 Go语言 并遵从Apache2.0协议开源. docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 ...

  10. C#中的等值判断1

    目录 简介 值类型和引用类型的相等比较 和相等比较相关的函数 string 和 System.Uri 的等值比较 泛型接口 IEquatable<T> 自定义比较方法 举例 总结 简介 最 ...