欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-07 21:45:08
本文为实战SpringCloud响应式微服务系列教程第十章,本章给出响应式RESTful服务完整代码示例。建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末。 1.搭建响应式RESTful服务。 在前面章节中我们讲了如何使用 Spring Initializer初始化响应式web应用,本节中就 ......

本文为实战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响应式微服务系列教程(第九章)