Spring-webflux

Spring 5.0 Spring-webflux 是一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务。

springboot2.0发布不久,最近研究了一下springboot2.0的新特性,其中就发现了webflux。

下面是spring-flux的一个demo话不多少上代码

使用webflux和MVC的区别就是在artifacId后面加上flux

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello world";
}
}

在webflux中有Handler和Router 的概念,分别与springmvc中的controllerr和equest mapper相对应,通俗的将就是handler就是真正处理请求的bean,可以在handler中编写处理请求的逻辑,而Router就是如何让请求找到对应的handler中的方法处理,下面我们来实现一个简单的handler和router。

@Component
public class HelloWorldHandler { public Mono<ServerResponse> helloWorld(ServerRequest request){
return ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(BodyInserters.fromObject("hello flux"));
} }

上面是一个简单的handler只相应了一个“hello flux” 字符串!

@Configuration
public class RouterConfig { @Autowired
private HelloWorldHandler helloWorldHandler; @Bean
public RouterFunction<?> helloRouter() {
return RouterFunctions.route(RequestPredicates.GET("/hello"), helloWorldHandler::helloWorld);
} }

上面是对应的router对应的是匹配一个get方式的/hello请求,然后调用helloWorldHandler中的helloWorld方法向浏览器输出一个文本类型的字符串

再来一个例子

@Component
public class UserHandler { @Autowired
private ReactiveRedisConnection connection; public Mono<ServerResponse> getTime(ServerRequest request) {
return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
.body(Mono.just("Now is " + new SimpleDateFormat("HH:mm:ss").format(new Date())), String.class);
}
public Mono<ServerResponse> getDate(ServerRequest request) {
return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
.body(Mono.just("Today is " + new SimpleDateFormat("yyyy-MM-dd").format(new Date())), String.class);
} public Mono<ServerResponse> sendTimePerSec(ServerRequest request) {
return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM)
.body(Flux.interval(Duration.ofSeconds(1)).map(l -> new SimpleDateFormat("HH:mm:ss").format(new Date())), String.class);
} public Mono<ServerResponse> register(ServerRequest request) {
Mono<Map> body = request.bodyToMono(Map.class);
return body.flatMap(map -> {
String username = (String) map.get("username");
String password = (String) map.get("password");
String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
return connection.stringCommands()
.set(ByteBuffer.wrap(username.getBytes()), ByteBuffer.wrap(hashedPassword.getBytes()));
}).flatMap(aBoolean -> {
Map<String, String> result = new HashMap<>();
ServerResponse serverResponse = null;
if (aBoolean){
result.put("message", "successful");
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(result));
}else {
result.put("message", "failed");
return ServerResponse.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(request));
}
}); } public Mono<ServerResponse> login(ServerRequest request) {
Mono<Map> body = request.bodyToMono(Map.class);
return body.flatMap(map -> {
String username = (String) map.get("username");
String password = (String) map.get("password");
return connection.stringCommands().get(ByteBuffer.wrap(username.getBytes())).flatMap(byteBuffer -> {
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes, 0, bytes.length);
String hashedPassword = null;
try {
hashedPassword = new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Map<String, String> result = new HashMap<>();
if (hashedPassword == null || !BCrypt.checkpw(password, hashedPassword)) {
result.put("message", "账号或密码错误");
return ServerResponse.status(HttpStatus.UNAUTHORIZED)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(result));
} else {
result.put("token", "无效token");
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(result));
}
});
});
} }

@Configuration
public class RouterConfig { @Autowired
private HelloWorldHandler helloWorldHandler; @Bean
public RouterFunction<?> helloRouter() {
return RouterFunctions.route(RequestPredicates.GET("/hello"), helloWorldHandler::helloWorld);
} @Autowired
private UserHandler userHandler; @Bean
public RouterFunction<ServerResponse> timerRouter() {
return RouterFunctions.route(RequestPredicates.GET("/time"), userHandler::getTime)
.andRoute(RequestPredicates.GET("/date"), userHandler::getDate);
} @Bean
public RouterFunction<?> routerFunction() {
return RouterFunctions.route(RequestPredicates.GET("/hello"), helloWorldHandler::helloWorld)
.andRoute(RequestPredicates.POST("/register"), userHandler::register)
.andRoute(RequestPredicates.POST("/login"), userHandler::login)
.andRoute(RequestPredicates.GET("/times"), userHandler::sendTimePerSec);
} }

Spring webflux的更多相关文章

  1. Spring Webflux: Kotlin DSL [片断]

    原文链接:https://dzone.com/articles/spring-webflux-kotlin-dsl-snippets 作者:Biju Kunjummen 译者:Jackie Tang ...

  2. Spring WebFlux开门迎客,却来了一位特殊客人

    话说Spring WebFlux已经出现有一段时间了,但是知道他的人并不是很多.这让他很是闷闷不乐. 还有更惨的是,那些敢于吃螃蟹的人在尝试了他之后,有的竟把代码重新改回到Spring MVC的同步模 ...

  3. 爸爸又给Spring MVC生了个弟弟叫Spring WebFlux

    情景引入 很早之前,Java就火起来了,是因为它善于开发和处理网络方面的应用. Java有一个爱好,就是喜欢制定规范标准,但自己又不善于去实现. 反倒是一些服务提供商使用它的规范标准来制造应用服务器而 ...

  4. Spring WebFlux 响应式编程学习笔记(一)

    各位Javaer们,大家都在用SpringMVC吧?当我们不亦乐乎的用着SpringMVC框架的时候,Spring5.x又悄(da)无(zhang)声(qi)息(gu)的推出了Spring WebFl ...

  5. Spring WebFlux 要革了谁的命?

    Spring WebFlux 要革了谁的命?  mp.weixin.qq.com 托梦 Java国王昨晚做了一个梦. 梦中有个白胡子老头儿,颇有仙风道骨, 告诉他说:“你们Java啊,实在是太弱了,连 ...

  6. 基于Angular和Spring WebFlux做个小Demo

    前言 随着Spring Boot2.0正式发布,Spring WebFlux正式来到了Spring Boot大家族里面.由于Spring WebFlux可以通过更少的线程去实现更高的并发和使用更少的硬 ...

  7. Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发WebFlux 支持两种编程风(姿)格(势) 使用@Controller这种基于注解

    概述 什么是 Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发框架. 要深入了解 Spring WebFlux, 首先要了知道 R ...

  8. 朱晔和你聊Spring系列S1E5:Spring WebFlux小探

    阅读PDF版本 本文会来做一些应用对比Spring MVC和Spring WebFlux,观察线程模型的区别,然后做一下简单的压力测试. 创建一个传统的Spring MVC应用 先来创建一个新的web ...

  9. 【SFA官方翻译】Spring WebFlux和Spring Cloud进行响应式微服务开发

    源码,修正一些错误: https://github.com/bigben0123/sample-spring-cloud-webflux 原创 SpringForAll社区 2018-05-18 作者 ...

  10. 初识Spring Webflux

    Important to know is that there are two ways to use Spring Webflux. One using annotations, which is ...

随机推荐

  1. node.js搭建Web服务器

    Node.js 博客搭建 一. 学习需求 Node 的安装运行 会安装node,搭建node环境 会运行node. 基础模块的使用 Buffer:二进制数据处理模块 Event:事件模块 fs:文件系 ...

  2. JS基础整理面试题

    1.DOM和BOM的区别 DOM:document object model;文档对象模型,提供操作页面元素的方法和属性BOM:browser object model;浏览器对象模型,提供一些属性和 ...

  3. FCC(ES6写法) Validate US Telephone Numbers

    如果传入字符串是一个有效的美国电话号码,则返回 true. 思路:用正则,参考网上资料和js高级程序设计(5.4RegExp类型). let telephoneCheck = str => /^ ...

  4. Kotlin基础

    1.函数也是对象,可以作为参数和返回值 2.使用驼峰命名,尽量避免下划线 3.public函数应当有说明文档 4.lambda中花括号内前后都应该有空格 5.空值安全检查  var s: String ...

  5. MYSQL数据库数据拆分之分库分表总结

    数据存储演进思路一:单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 数据存储演进思路二:单库多表 随着用户数量的 ...

  6. JAVA设计模式—观察者模式和Reactor反应堆模式

    被观察者(主题)接口 定义主题对象接口 /**抽象主题角色: 这个主题对象在状态上发生变化时,会通知所有观察者对象 也叫事件对象 */ public interface Subject { //增加一 ...

  7. [Swift]LeetCode82. 删除排序链表中的重复元素 II | Remove Duplicates from Sorted List II

    Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numb ...

  8. [Swift]LeetCode299. 猜数字游戏 | Bulls and Cows

    You are playing the following Bulls and Cows game with your friend: You write down a number and ask ...

  9. [Swift]LeetCode632. 最小区间 | Smallest Range

    You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...

  10. [Swift]LeetCode866. 回文素数 | Prime Palindrome

    Find the smallest prime palindrome greater than or equal to N. Recall that a number is prime if it's ...