资讯专栏INFORMATION COLUMN

Spring webflux 函数式编程web框架

Eastboat / 1122人阅读

摘要:是一个全新的非堵塞的函数式框架,可以用来构建异步的非堵塞的事件驱动的服务。上面是一个简单的只相应了一个字符串上面是对应的对应的是匹配一个方式的请求,然后调用中的方法向浏览器输出一个文本类型的字符串再来一个例子账号或密码错误无效

Spring webflux

Spring 5.0 Spring webflux 是一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务。
springboot2.0发布不久,最近研究了一下springboot2.0的新特性,其中就发现了webflux。

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

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


    org.springframework.boot
    spring-boot-starter-parent
    2.0.0.RELEASE


    org.springframework.boot
    spring-boot-starter-webflux
@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 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 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 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 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 register(ServerRequest request) {
        Mono 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 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 login(ServerRequest request) {
        Mono 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 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 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);
    }

}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74228.html

相关文章

  • Spring Boot 2 快速教程:WebFlux 快速入门(二)

    摘要:响应式编程是基于异步和事件驱动的非阻塞程序,只是垂直通过在内启动少量线程扩展,而不是水平通过集群扩展。三特性常用的生产的特性如下响应式编程模型适用性内嵌容器组件还有对日志消息测试及扩展等支持。 摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 02:WebFlux 快速入门实践 文章工程: JDK...

    gaara 评论0 收藏0
  • Spring Boot 2.x 系列教程:WebFlux 系列教程大纲(一)

    摘要:使用则需要及以上版本。开发使用框架七系列教程目录系列教程大纲快速入门实践实践整合整合中和实践整合中实现缓存中实现通信集成测试及部署实战图书管理系统 WebFlux 系列教程大纲 一、背景 大家都知道,Spring Framework 是 Java/Spring 应用程序跨平台开发框架,也是 Java EE(Java Enterprise Edition) 轻量级框架,其 Spring ...

    jone5679 评论0 收藏0
  • 《Java编程方法论:响应RxJava与代码设计实战》序

    摘要:原文链接编程方法论响应式与代码设计实战序,来自于微信公众号次灵均阁正文内容在一月的架构和设计趋势报告中,响应式编程和函数式仍旧编列在第一季度的早期采纳者中。 原文链接:《Java编程方法论:响应式RxJava与代码设计实战》序,来自于微信公众号:次灵均阁 正文内容 在《2019 一月的InfoQ 架构和设计趋势报告》1中,响应式编程(Reactive Programming)和函数式...

    PAMPANG 评论0 收藏0
  • SpringBoot Kotlin 系列之HTML与WebFlux

    摘要:上一章我们提到过与,对于具体的介绍没说到,这一章我在这里简单介绍一下,既然提到和,那肯定得提到什么是响应式编程,什么是。 showImg(https://segmentfault.com/img/remote/1460000018819338?w=1024&h=500); 上一章我们提到过Mono 与 Flux,对于具体的介绍没说到,这一章我在这里简单介绍一下,既然提到Mono和Flu...

    crossoverJie 评论0 收藏0
  • 华为官方首发Spring响应微服务,Spring+Boot+Cloud三管齐下

    摘要:今天小编就来分享一份华为刚刚首发的响应式微服务实战这份主要包含响应式微服务架构实现过程中所应具备的技术体系和工程实践,在组织结构上分如下篇。 今天小编就来分享一份华为刚刚首发的Spring响应式微服务(Spring Boot 2+Spring 5+Spring Cloud实战)! 这份PDF...

    cangck_X 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<