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. Android APK反编译:APKtool使用详解

    导言:在我们安卓开发当中,我们不仅需要掌握基础的开发技能,也需要掌握软件的安全技能,这样才可以让我们的软件能够成为一款能够真正可以进行发布的软件,同时也可以让自己的核心技术不会被别人所盗取. 第一步. ...

  2. JNI实战(二):Java 调用 C

    1. JNI Env 和 Java VM 关系说明 JNIEnv 是 Java的本地化环境,是Java与C的交互的重要桥梁. 在Android上,一个进程对应一个JavaVM,也就是一个app对应一个 ...

  3. SUSE12Sp3安装配置.net core 生产环境(1)-IP,DNS,网关,SSH,GIT

    1.新增用户 sudo useradd 用户名 sudo passwd 用户名 这个时候会提示你输入密码,输入两次密码即可 2.静态 IP 设置 1.设置 IP 地址 sudo vi /etc/sys ...

  4. [Swift]LeetCode54. 螺旋矩阵 | Spiral Matrix

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  5. [Swift]LeetCode219. 存在重复元素 II | Contains Duplicate II

    Given an array of integers and an integer k, find out whether there are two distinct indices i and j ...

  6. [Swift]LeetCode914.一副牌中的X | X of a Kind in a Deck of Cards

    In a deck of cards, each card has an integer written on it. Return true if and only if you can choos ...

  7. [Swift]LeetCode358. 按距离为k隔离重排字符串 $ Rearrange String k Distance Apart

    Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...

  8. 学习HTML5 canvas遇到的问题

    学习HTML5 canvas遇到的问题 1. 非零环绕原则(nonzZero rule) 非零环绕原则是canvas在进行填充的时候是否要进行填充的判断依据. 在判断填充的区域拉一条线出来,拉到图形的 ...

  9. 优化之Sequence Generator组件

    优化Sequence Generator组件,需创建一个可重用的序列生成器,并同时在多个Mappings中使用它 关于Number of Cached Values Sequence Generato ...

  10. Django中使用geetest实现滑动验证

    下载第三方模块 导入模块social-auth-app-django 和geetest 提前去官网下载gt.js或者引入http://static.geetest.com/static/tools/g ...