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

1.搭建响应式RESTful服务。

在前面章节中我们讲了如何使用 Spring Initializer初始化响应式web应用,本节中就不再做过多介绍(请回顾第九章内容)。

在学习本章内容之前需要了解mongodb以及redis,mongodb以及redis可查阅相关资料进行全面了解,并在本地环境搭建mongodb和redis。

2.application.yml文件配置

server:
port: 9801
spring:
application:
name: advert
data:
mongodb:
uri: mongodb://localhost:27017/db_advert
http:
encoding:
force: true
charset: UTF-8
enabled: true
redis:
host: 127.0.0.1
password: 123456
logback:
level: info

以上配置代码是我们目前学习的响应式RESTful服务的全部配置,配置比较简单,spring.data.mongodb.uri: mongodb://localhost:27017/db_advertspring.data.redis是我们服务的核心配置,我们知道传统的数据库是不支持响应式数据读取的,所以这里使用mongodb和redis代替。

3.集成响应式的MongoDB

springboot 本身提供了cassandra/couchbase/mongodb/redis这几个NoSQL数据库的响应式驱动:

阻塞式的spring-boot-starter-data-mongodb 改为响应式的mongodb依赖spring-boot-starter-data-mongodb-reactive:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

(1)编写实体类:

/**
* 广告投放
*/
@Document(collection="advert")//集合名
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Advert implements Serializable {
private static final long serialVersionUID = -8985545025018238754L;
/**
* 主键
*/
@Id
private String id;
/**
* 内容
*/
private String content;
/**
* 发布人
*/
private Long userId;
/**
* 创建时间
*/
private Date creatData;
/**
* 图片地址
*/
private String imgUrl;
/**
* 视频地址
*/
private String videoUrl;
/**
* 广告类型(视频图片)
*/
private String advertType;
/**
* 今日投放地区
*/
private String launchArea;
/**
* 投放时长(小时为单位)
*/
private int durationTime;
/**
* 广告类型
*/
private int classify;
/**
* 计费方式
*/
private int billingMode;
/**
* 展示位置(首页轮播,其他轮播,首页其他位置,其他)
*/
private int displayPosition;
/**
* 广告主题
*/
private String advertTitle;
/**
* 是否需要自定义展示页面
*/
private int isCustom;
/**
* 索引关键词
*/
private String keyWords;
}

其中@document把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档,标注在实体类上,类似于hibernate的entity注解。其他注解均为lombok的注解。

(2)编写repository接口

import com.shmc.advert.model.po.Advert;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.data.mongodb.repository.Tailable;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
@Repository
public interface AdvertRepository extends ReactiveMongoRepository<Advert,Long> {
@Tailable
Flux<Advert> findBy();
}

其中@Repository是org.springframework.stereotype.Repository的注解,这个大家应该都很熟悉了不做解释。

从以上代码中我们可以清楚看到AdvertRepository 继承了ReactiveMongoRepository,ReactiveMongoRepository正是我们依赖的maven响应式mongodb-reactive中的类,其中@Tailable注解,该注解类似于Linux中的tail ,可以将DB的变化以响应式流的方式获取到并推送给前端。

除了可以继承ReactiveMongoRepository之外我们还可以通过注入MongoTemplate来操作mongodb,但是MongoTemplate做不到实时监控和主动推送。如:

@Autowired
MongoTemplate mongoTemplate;

(3)编写Service接口以及实现类

Service接口:

import com.shmc.advert.model.po.Advert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; public interface AdvertService {
Mono<Advert> saveAdvert(Advert advert);
Mono<Advert> findById(String id);
Flux<Advert> findAll();
Flux<Advert> findByAll();
}

Service实现类:

@Service
public class AdvertServiceImpl implements AdvertService {
@Autowired
MongoTemplate mongoTemplate;
@Autowired
private AdvertRepository advertRepository;
@Override
public Mono<Advert> saveAdvert(Advert advert){
advert.setId(new IdWorker().nextId());
advert.setCreatData(new Date());
mongoTemplate.insert(advert);
return Mono.just(advert);
} @Override
public Mono<Advert> findById(String id){
Query query = new Query(Criteria.where("id").is(id));
return Mono.just(mongoTemplate.findOne(query,Advert.class));
} @Override
public Flux<Advert> findAll(){
return advertRepository.findAll();
} @Override
public Flux<Advert> findByAll(){
return advertRepository.findBy();
}
}

(4)编写Controller

import com.shmc.advert.model.po.Advert;
import com.shmc.advert.service.AdvertService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import java.time.Duration; @RestController
@RequestMapping("/advert")
public class AdvertController {
@Autowired
private AdvertService advertService; @PostMapping("/saveAdvert")
public Mono<Advert> saveAdvert(@RequestBody Advert advert){
return advertService.saveAdvert(advert);
} @GetMapping("/findById/{id}")
public Mono<Advert> findById(@PathVariable String id){
return advertService.findById(id);
}
/**
* 以stream+json流的方式推送到客户端
* @return
*/
@GetMapping(value = "/findAllPreSec", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<Advert> findAllPreSec() {
return advertService.findAll().delayElements(Duration.ofSeconds(1));
} /**
* 数据变更
* @return
*/
@GetMapping(value = "/findByAll", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<Advert> findByAll(){
return advertService.findByAll();
}
}

至此基于RESTful的响应式服务我们全部完成了,启动程序访问“/advert/findAllPreSec"接口和”/advert/findByAll“接口就可以看到响应式的数据推送了。

findAllPreSec这个方法。使用了delayElements使得每隔一秒钟获取一条数据发送给客户端,以“异步响应式流”的方式逐条推送。

这里指定了MediaType是APPLICATION_STREAM_JSON,即application/stream+json格式。

在浏览器中就可以看到每隔一秒出现一条记录。运行程序,访问findByAll接口,然后测试调用save接口添加advert数据,或者直接通过MongoDB Compass客户端添加Stu数据,就会看到在页面中实时看到新添加的数据了。

下一章会吧代码上传到gitee,各位看官如有需要请自行下载。

系列章节目录

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

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

实战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响应式微服务系列教程(第八章)构建响应式RESTful服务

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

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

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

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

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

  9. 玩转Windows服务系列——使用Boost.Application快速构建Windows服务

    玩转Windows服务系列——创建Windows服务一文中,介绍了如何快速使用VS构建一个Windows服务.Debug.Release版本的注册和卸载,及其原理和服务运行.停止流程浅析分别介绍了Wi ...

随机推荐

  1. APP设计与开发(ui篇)

    这篇文章是我个人在开发与设计APP的所用的一些设计思路,仅用于和大家分享知识并不是什么设计标准之类的.主要说明App的开发中是如何来开发与组织UI部分. UI模块结构 在项目中建立ui包用于存放ui类 ...

  2. Ubuntu 搭建Zookeeper服务

    1.下载安装包 官方下载地址http://apache.fayea.com/zookeeper/ 2.安装 安装前确保系统已安装过JDK,JDK安装过程可参照 2.1 解压下载好的tar.gz安装包到 ...

  3. idea必备快捷键

    ctrl + F: 在当前文件进行文本查找 ctrl + R: 在当前文件进行文本的替换 ctrl + Z: 撤销操作 ctrl + Y:删除光所在的行 或者选中的行 ctrl + D: 复制光标所在 ...

  4. 一个PHP文件搞定微信H5支付

     / 更新于 2018-07-02 / 8 条评论 过年期间也坚持要撸码啊接着给博客除草,在这个小除夕是情人节的一天,祝大家新年快乐,情人节能够顺利脱单~~~ 回归正题,这篇文章介绍一下微信H5支付, ...

  5. CSS3自定义浏览器滚动条样式

    一个完整滚动条右以下部分组成: ::-webkit-scrollbar 滚动条整体部分,常用属性:width,height,background,border: ::-webkit-scrollbar ...

  6. ELK 学习笔记之 elasticsearch基本概念和CRUD

    elasticsearch基本概念和CRUD: 基本概念: CRUD: 创建索引: curl -XPUT 'http://192.168.1.151:9200/library/' -d '{" ...

  7. .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础 -2

    上节中,我们初步的介绍了一下NetCore的一些基础知识,为了控制篇幅(其实也是因为偷懒),我将NetCore 基础分为两部分来写. 0.WebAPI 项目的建立 1..NetCore 项目执行(加载 ...

  8. Java字段初始化规律

    首先先附上一段代码:public class InitializeBlockDemo { public static void main(String[] args) { InitializeBloc ...

  9. Spring-Data-Jpa使用总结

    参考资源列表 官方文档:https://docs.spring.io/spring-data/jpa/docs/2.1.5.RELEASE/reference/html/ <Spring Dat ...

  10. requests模块(post)请求篇

    '''利用parse模块模拟post请求分析百度词典分析步骤:1. 打开F122. 尝试输入单词girl,发现每敲一个字母后都有请求3. 请求地址是 http://fanyi.baidu.com/su ...