当前位置: 首页 > news >正文

Springboot 整合WebFlux 实现RESTFUI风格API 及简单的CRUD

这里简单介绍下springboot整合webFlux(入门) ,使用netty通信。

首先是创建一个springboot项目,这里就不介绍怎么创建了。

接下来是导入依赖包:

 

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

(使用这个依赖包后,不要再导入spring-boot-starter-web包了,因为我们webflux使用的是netty)

 

然后是创建一个简单的pojo:

User.java 
 

package com.test.webflux.pojo;

import lombok.Data;

/**
 * @Author:JCccc
 * @Description:
 * @Date: created in 16:08 2019/5/30
 */
@Data

public class User {
    /**
     * id
     */
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 描述
     */
    private String desc;

}

接下来是dao层(netty不支持mysql,所以想要对数据进行CRUD可以采取整合mongodb和redis),这里我暂且采用的ConcurrentMap来操作数据:

UserRepository.java

package com.test.webflux.dao;

import com.test.webflux.pojo.User;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @Author:JCccc
 * @Description:
 * @Date: created in 16:30 2019/5/30
 */
@Repository
public class UserRepository {

    private ConcurrentMap<Long,User> repository = new ConcurrentHashMap<>();

    private static final AtomicLong idGenerator = new AtomicLong(0);


    public Long save(User user){
        Long id=idGenerator.incrementAndGet();
        user.setId(id);
        repository.put(id, user);
        return id;
    }

    public Collection<User> findAll() {
        return repository.values();
    }

    public User findUserById(Long id) {
        return repository.get(id);
    }

    public Long updateUser(User user) {
        repository.put(user.getId(), user);
        return user.getId();
    }

    public Long deleteUser(Long id) {
        repository.remove(id);
        return id;
    }
}

接下来是handler层,这里简单列举了对ConcurrentMap进行CRUD的几个方法,

UserHandler.java

package com.test.webflux.handler;

import com.test.webflux.dao.UserRepository;
import com.test.webflux.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @Author:JCccc
 * @Description:
 * @Date: created in 16:38 2019/5/30
 */
@Component
public class UserHandler {
    private final UserRepository userRepository;
    @Autowired
    public UserHandler(UserRepository userRepository) {
        this.userRepository = userRepository;
    }


    public Mono<Long> save(User user) {
        return Mono.create(userMonoSink -> userMonoSink.success(userRepository.save(user)));
    }

    public Mono<User> findUserById(Long id) {
        return Mono.justOrEmpty(userRepository.findUserById(id));
    }

    public Flux<User> findAllUser() {
        return Flux.fromIterable(userRepository.findAll());
    }

    public Mono<Long> modifyUser(User user) {
        return Mono.create(userMonoSink -> userMonoSink.success(userRepository.updateUser(user)));
    }

    public Mono<Long> deleteUser(Long id) {
        return Mono.create(userMonoSink -> userMonoSink.success(userRepository.deleteUser(id)));
    }
}

最后,创建下controller层写几个API(这里采用restful风格):

UserWebFluxController.java

package com.test.webflux.controller;

import com.test.webflux.handler.UserHandler;
import com.test.webflux.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @Author:JCccc
 * @Description:
 * @Date: created in 16:44 2019/5/30
 */

@RestController
@RequestMapping(value = "/user")
public class UserWebFluxController {

    @Autowired
    private UserHandler userHandler;

    /**
     * 根据ID查询某个User
     * @param id
     * @return
     */
    @GetMapping(value = "/{id}")
    public Mono<User> findUserById(@PathVariable("id") Long id) {
        return userHandler.findUserById(id);
    }

    /**
     * 查找所有User
     * @return
     */
    @GetMapping()
    public Flux<User> findAllUser() {
        return userHandler.findAllUser();
    }

    /**
     * 插入User
     * @param user
     * @return
     */
    @PostMapping()
    public Mono<Long> saveUser(@RequestBody User user) {
        return userHandler.save(user);
    }

    /**
     * 修改User
     * @param user
     * @return
     */
    @PutMapping()
    public Mono<Long> modifyUser(@RequestBody User user) {
        return userHandler.modifyUser(user);
    }

    /**
     * 根据ID删除User
     * @param id
     * @return
     */
    @DeleteMapping(value = "/{id}")
    public Mono<Long> deleteUser(@PathVariable("id") Long id) {
        return userHandler.deleteUser(id);
    }
}

到此,简单的webflux入门整合已经完成了。

那么我们最后把项目跑起来,简单测试一下,

接下来使用postman调用下插入user接口 :

再调一下查询接口:

 

OK,其余的接口也是一样调用,那么简单的介绍就此完毕了。

(PS:想了解更多的,可以去查下mono和flux的相关资料,可以往上翻下,controller里面用到了Mono)

Mono 和 Flux 适用于两个场景,即: 
 Mono:实现发布者,并返回 0 或 1 个元素,即单对象。 
 Flux:实现发布者,并返回 N 个元素,即 List 列表对象。 
 有人会问,这为啥不直接返回对象,比如返回 City/Long/List。 
 原因是,直接使用 Flux 和 Mono 是非阻塞写法,相当于回调方式。 
 利用函数式可以减少了回调,因此会看不到相关接口。这恰恰是 WebFlux 的好处:集合了非阻塞 + 异步 

 

相关文章:

  • Springboot 读取配置文件application.properties (yml)的四种方式
  • Springboot 指定获取自己写的配置properties文件的值
  • JAVA AES加密解密工具类
  • Springboot 快速了解 事务回滚@Transactional
  • Springboot Mybatis使用pageHelper实现分页查询
  • JAVA 雪花算法 唯一ID生成工具类
  • 灵魂的拷问 怎么将代码写得让人无法维护?
  • 灵魂的拷问 Hashtable的命名
  • 运行ElasticSearch报错:uncaught exception in thread [main] org.elasticsearch.bootstrap.StartupException
  • JAVA 8 Stream 常用操作
  • JAVA 8 Stream优雅使用结合实战分析
  • mysql Error Code: 1175. You are using safe update mode and you tried to update a table without ....
  • SpringBoot 整合WebSocket 简单实战案例
  • Kafka Windows运行错误:找不到或无法加载主类 Files\kafka\kafka_2.12-2.0.0\libs\activation-1.1.1.ja r;C:\Program
  • Kafka Windows运行错误:创建消费者报错 consumer zookeeper is not a recognized option
  • @angular/forms 源码解析之双向绑定
  • canvas 高仿 Apple Watch 表盘
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • DOM的那些事
  • HTTP中的ETag在移动客户端的应用
  • JAVA之继承和多态
  • Mysql数据库的条件查询语句
  • Node + FFmpeg 实现Canvas动画导出视频
  • php ci框架整合银盛支付
  • React+TypeScript入门
  • react-native 安卓真机环境搭建
  • scrapy学习之路4(itemloder的使用)
  • Spark RDD学习: aggregate函数
  • 半理解系列--Promise的进化史
  • 多线程事务回滚
  • 数据可视化之 Sankey 桑基图的实现
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​520就是要宠粉,你的心头书我买单
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #if #elif #endif
  • #数学建模# 线性规划问题的Matlab求解
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • ()、[]、{}、(())、[[]]命令替换
  • (12)Hive调优——count distinct去重优化
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .Net MVC4 上传大文件,并保存表单
  • .net反混淆脱壳工具de4dot的使用
  • .NET开源快速、强大、免费的电子表格组件