實(shí)戰(zhàn)SpringCloud響應(yīng)式微服務(wù)系列教程(第十章)

作者:瑾年 微信公眾號: Java知音

1.搭建響應(yīng)式RESTful服務(wù)愧膀。

在前面章節(jié)中我們講了如何使用 Spring Initializer初始化響應(yīng)式web應(yīng)用沽讹,本節(jié)中就不再做過多介紹

在學(xué)習(xí)本章內(nèi)容之前需要了解mongodb以及redis,mongodb以及redis可查閱相關(guān)資料進(jìn)行全面了解唉擂,并在本地環(huán)境搭建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

以上配置代碼是我們目前學(xué)習(xí)的響應(yīng)式RESTful服務(wù)的全部配置艳吠,配置比較簡單,spring.data.mongodb.uri: mongodb://localhost:27017/db_advertspring.data.redis是我們服務(wù)的核心配置局骤,我們知道傳統(tǒng)的數(shù)據(jù)庫是不支持響應(yīng)式數(shù)據(jù)讀取的攀圈,所以這里使用mongodb和redis代替。

3.集成響應(yīng)式的MongoDB

springboot 本身提供了cassandra/couchbase/mongodb/redis這幾個NoSQL數(shù)據(jù)庫的響應(yīng)式驅(qū)動:

阻塞式的spring-boot-starter-data-mongodb 改為響應(yīng)式的mongodb依賴spring-boot-starter-data-mongodb-reactive:

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

(1)編寫實(shí)體類:

/**
 * 廣告投放
 */
@Document(collection="advert")//集合名
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Advert implements Serializable {
    private static final long serialVersionUID = -8985545025018238754L;
    /**
     * 主鍵
     */
    @Id
    private String id;
    /**
     * 內(nèi)容
     */
    private String content;
    /**
     * 發(fā)布人
     */
    private Long userId;
    /**
     * 創(chuàng)建時間
     */
    private Date creatData;
    /**
     * 圖片地址
     */
    private String imgUrl;
    /**
     * 視頻地址
     */
    private String videoUrl;
    /**
     * 廣告類型(視頻圖片)
     */
    private String advertType;
    /**
     * 今日投放地區(qū)
     */
    private String launchArea;
    /**
     * 投放時長(小時為單位)
     */
    private int durationTime;
    /**
     * 廣告類型
     */
    private int classify;
    /**
     * 計費(fèi)方式
     */
    private int billingMode;
    /**
     * 展示位置(首頁輪播峦甩,其他輪播赘来,首頁其他位置,其他)
     */
    private int displayPosition;
    /**
     * 廣告主題
     */
    private String advertTitle;
    /**
     * 是否需要自定義展示頁面
     */
    private int isCustom;
    /**
     * 索引關(guān)鍵詞
     */
    private String keyWords;
}

其中@document把一個java類聲明為mongodb的文檔,可以通過collection參數(shù)指定這個類對應(yīng)的文檔,標(biāo)注在實(shí)體類上,類似于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的注解嗦篱,這個大家應(yīng)該都很熟悉了不做解釋。

從以上代碼中我們可以清楚看到AdvertRepository 繼承了ReactiveMongoRepository幌缝,ReactiveMongoRepository正是我們依賴的maven響應(yīng)式mongodb-reactive中的類灸促,其中@Tailable注解,該注解類似于Linux中的tail 狮腿,可以將DB的變化以響應(yīng)式流的方式獲取到并推送給前端腿宰。

除了可以繼承ReactiveMongoRepository之外我們還可以通過注入MongoTemplate來操作mongodb,但是MongoTemplate做不到實(shí)時監(jiān)控和主動推送缘厢。如:

@Autowired
MongoTemplate mongoTemplate;

(3)編寫Service接口以及實(shí)現(xiàn)類

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實(shí)現(xiàn)類:

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

    /**
     * 數(shù)據(jù)變更
     * @return
     */
    @GetMapping(value = "/findByAll", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
    public Flux<Advert> findByAll(){
        return advertService.findByAll();
    }
}

至此基于RESTful的響應(yīng)式服務(wù)我們?nèi)客瓿闪顺远龋瑔映绦蛟L問“/advert/findAllPreSec"接口和”/advert/findByAll“接口就可以看到響應(yīng)式的數(shù)據(jù)推送了。

findAllPreSec這個方法贴硫。使用了delayElements使得每隔一秒鐘獲取一條數(shù)據(jù)發(fā)送給客戶端椿每,以“異步響應(yīng)式流”的方式逐條推送。

這里指定了MediaType是APPLICATION_STREAM_JSON英遭,即application/stream+json格式间护。

在瀏覽器中就可以看到每隔一秒出現(xiàn)一條記錄。運(yùn)行程序挖诸,訪問findByAll接口汁尺,然后測試調(diào)用save接口添加advert數(shù)據(jù),或者直接通過MongoDB Compass客戶端添加Stu數(shù)據(jù)多律,就會看到在頁面中實(shí)時看到新添加的數(shù)據(jù)了痴突。

下一章會吧代碼上傳到gitee,各位看官如有需要請自行下載狼荞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辽装,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子相味,更是在濱河造成了極大的恐慌拾积,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丰涉,死亡現(xiàn)場離奇詭異拓巧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)昔搂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門玲销,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摘符,你說我怎么就攤上這事贤斜〔叻停” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵瘩绒,是天一觀的道長猴抹。 經(jīng)常有香客問我,道長锁荔,這世上最難降的妖魔是什么蟀给? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮阳堕,結(jié)果婚禮上跋理,老公的妹妹穿的比我還像新娘。我一直安慰自己恬总,他們只是感情好前普,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著壹堰,像睡著了一般拭卿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贱纠,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天峻厚,我揣著相機(jī)與錄音,去河邊找鬼谆焊。 笑死惠桃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辖试。 我是一名探鬼主播刽射,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼剃执!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起懈息,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肾档,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辫继,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怒见,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年姑宽,在試婚紗的時候發(fā)現(xiàn)自己被綠了遣耍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡炮车,死狀恐怖舵变,靈堂內(nèi)的尸體忽然破棺而出酣溃,到底是詐尸還是另有隱情,我是刑警寧澤纪隙,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布赊豌,位于F島的核電站,受9級特大地震影響绵咱,放射性物質(zhì)發(fā)生泄漏碘饼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一悲伶、第九天 我趴在偏房一處隱蔽的房頂上張望艾恼。 院中可真熱鬧,春花似錦麸锉、人聲如沸钠绍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽五慈。三九已至,卻和暖如春主穗,著一層夾襖步出監(jiān)牢的瞬間泻拦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工忽媒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留争拐,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓晦雨,卻偏偏與公主長得像架曹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闹瞧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容