實戰SpringCloud響應式微服務系列教程(第十章)響應式RESTful服務完整代碼示例

本文爲實戰SpringCloud響應式微服務系列教程第十章,本章給出響應式RESTful服務完整代碼示例。建議沒有以前基礎的童鞋,先看以前的章節,章節目錄放在文末。前端

1.搭建響應式RESTful服務。

在前面章節中咱們講了如何使用 Spring Initializer初始化響應式web應用,本節中就再也不作過多介紹(請回顧第九章內容)。java

在學習本章內容以前須要瞭解mongodb以及redis,mongodb以及redis可查閱相關資料進行全面瞭解,並在本地環境搭建mongodb和redis。react

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代替。git

3.集成響應式的MongoDB

springboot 自己提供了cassandra/couchbase/mongodb/redis這幾個NoSQL數據庫的響應式驅動:web

阻塞式的spring-boot-starter-data-mongodb 改成響應式的mongodb依賴spring-boot-starter-data-mongodb-reactive:redis

<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的註解。spring

(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的註解,這個你們應該都很熟悉了不作解釋。mongodb

從以上代碼中咱們能夠清楚看到AdvertRepository 繼承了ReactiveMongoRepository,ReactiveMongoRepository正是咱們依賴的maven響應式mongodb-reactive中的類,其中@Tailable註解,該註解相似於Linux中的tail ,能夠將DB的變化以響應式流的方式獲取到並推送給前端。數據庫

除了能夠繼承ReactiveMongoRepository以外咱們還能夠經過注入MongoTemplate來操做mongodb,可是MongoTemplate作不到實時監控和主動推送。如:json

@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響應式微服務系列教程(第九章)

相關文章
相關標籤/搜索