SpringBoot2使用WebFlux函数式编程的方法
本文只是简单使用springboot2使用webflux的函数式编程简单使用,后续会继续写关于webflux相关的文章。
最近一直在研究webflux,后续会陆续出一些相关的文章。
首先看一下srping官网上的一张图,对比一下springmvc和spring webflux,如图:
在查看一下webflux的官方文档:,webflux提供了函数式编程,本文简单介绍一下webflux函数式编程简单使用。
新建项目
创建一个项目,pom文件中引入webflux依赖,完整pom文件如下:
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.dalaoyang</groupid> <artifactid>springboot2_webflux</artifactid> <version>0.0.1-snapshot</version> <packaging>jar</packaging> <name>springboot2_webflux</name> <description>springboot2_webflux</description> <parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.0.3.release</version> <relativepath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceencoding>utf-8</project.build.sourceencoding> <project.reporting.outputencoding>utf-8</project.reporting.outputencoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-webflux</artifactid> </dependency> </dependencies> <build> <plugins> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> </plugin> </plugins> </build> </project>
首先试试引入webflux依赖之后,springmvc方式是否还能使用,新建一个hellocontroller,完整代码如下,执行后发现,是可以正常执行访问的,这其实就是我们所说的注解式编程。
package com.dalaoyang.controller; import org.springframework.web.bind.annotation.getmapping; import org.springframework.web.bind.annotation.restcontroller; /** * @author dalaoyang * @project springboot_learn * @package com.dalaoyang.controller * @email yangyang@dalaoyang.cn * @date 2018/7/30 */ @restcontroller public class hellocontroller { @getmapping("hello") public string hello(){ return "hello this is springwebflux"; } }
结果如图:
接下来使用函数式编程,首先查阅一下官方文档,如图:
我们需要创建一个handlerfunction返回值为mono,新建一个hihandler,里面写一个方法hi,完整代码如下:
package com.dalaoyang.handler; import org.springframework.http.mediatype; import org.springframework.stereotype.component; import org.springframework.web.reactive.function.bodyinserters; import org.springframework.web.reactive.function.server.serverrequest; import org.springframework.web.reactive.function.server.serverresponse; import reactor.core.publisher.mono; /** * @author dalaoyang * @project springboot_learn * @package com.dalaoyang.handler * @email yangyang@dalaoyang.cn * @date 2018/7/30 */ @component public class hihandler { public mono<serverresponse> hi(serverrequest request) { return serverresponse.ok().contenttype(mediatype.application_json) .body(bodyinserters.fromobject("hi , this is springwebflux")); } }
其中serverresponse是相应的封装对象,下面是它的源码,其中包含了响应状态,响应头等等,代码如下:
package org.springframework.web.reactive.function.server; import java.net.uri; import java.time.zoneddatetime; import java.util.list; import java.util.map; import java.util.set; import java.util.function.bifunction; import java.util.function.consumer; import org.reactivestreams.publisher; import org.springframework.core.parameterizedtypereference; import org.springframework.http.cachecontrol; import org.springframework.http.httpheaders; import org.springframework.http.httpmethod; import org.springframework.http.httpstatus; import org.springframework.http.mediatype; import org.springframework.http.responsecookie; import org.springframework.http.codec.httpmessagewriter; import org.springframework.http.server.reactive.serverhttpresponse; import org.springframework.util.multivaluemap; import org.springframework.web.reactive.function.bodyinserter; import org.springframework.web.reactive.result.view.viewresolver; import org.springframework.web.server.serverwebexchange; import reactor.core.publisher.mono; public interface serverresponse { httpstatus statuscode(); httpheaders headers(); multivaluemap<string, responsecookie> cookies(); mono<void> writeto(serverwebexchange var1, serverresponse.context var2); static serverresponse.bodybuilder from(serverresponse other) { return new defaultserverresponsebuilder(other); } static serverresponse.bodybuilder status(httpstatus status) { return new defaultserverresponsebuilder(status); } static serverresponse.bodybuilder status(int status) { return new defaultserverresponsebuilder(status); } static serverresponse.bodybuilder ok() { return status(httpstatus.ok); } static serverresponse.bodybuilder created(uri location) { serverresponse.bodybuilder builder = status(httpstatus.created); return (serverresponse.bodybuilder)builder.location(location); } static serverresponse.bodybuilder accepted() { return status(httpstatus.accepted); } static serverresponse.headersbuilder<?> nocontent() { return status(httpstatus.no_content); } static serverresponse.bodybuilder seeother(uri location) { serverresponse.bodybuilder builder = status(httpstatus.see_other); return (serverresponse.bodybuilder)builder.location(location); } static serverresponse.bodybuilder temporaryredirect(uri location) { serverresponse.bodybuilder builder = status(httpstatus.temporary_redirect); return (serverresponse.bodybuilder)builder.location(location); } static serverresponse.bodybuilder permanentredirect(uri location) { serverresponse.bodybuilder builder = status(httpstatus.permanent_redirect); return (serverresponse.bodybuilder)builder.location(location); } static serverresponse.bodybuilder badrequest() { return status(httpstatus.bad_request); } static serverresponse.headersbuilder<?> notfound() { return status(httpstatus.not_found); } static serverresponse.bodybuilder unprocessableentity() { return status(httpstatus.unprocessable_entity); } public interface context { list<httpmessagewriter<?>> messagewriters(); list<viewresolver> viewresolvers(); } public interface bodybuilder extends serverresponse.headersbuilder<serverresponse.bodybuilder> { serverresponse.bodybuilder contentlength(long var1); serverresponse.bodybuilder contenttype(mediatype var1); serverresponse.bodybuilder hint(string var1, object var2); <t, p extends publisher<t>> mono<serverresponse> body(p var1, class<t> var2); <t, p extends publisher<t>> mono<serverresponse> body(p var1, parameterizedtypereference<t> var2); mono<serverresponse> syncbody(object var1); mono<serverresponse> body(bodyinserter<?, ? super serverhttpresponse> var1); mono<serverresponse> render(string var1, object... var2); mono<serverresponse> render(string var1, map<string, ?> var2); } public interface headersbuilder<b extends serverresponse.headersbuilder<b>> { b header(string var1, string... var2); b headers(consumer<httpheaders> var1); b cookie(responsecookie var1); b cookies(consumer<multivaluemap<string, responsecookie>> var1); b allow(httpmethod... var1); b allow(set<httpmethod> var1); b etag(string var1); b lastmodified(zoneddatetime var1); b location(uri var1); b cachecontrol(cachecontrol var1); b varyby(string... var1); mono<serverresponse> build(); mono<serverresponse> build(publisher<void> var1); mono<serverresponse> build(bifunction<serverwebexchange, serverresponse.context, mono<void>> var1); } }
在回过头了看上面官方文档的图片,还需要配置一个路由来类似@requestmapping的功能,通过routerfunctions.route(requestpredicate, handlerfunction)提供了一个路由器函数默认实现,新建一个hirouter,代码如下:
package com.dalaoyang.router; import com.dalaoyang.handler.hihandler; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.http.mediatype; import org.springframework.web.reactive.function.server.requestpredicates; import org.springframework.web.reactive.function.server.routerfunction; import org.springframework.web.reactive.function.server.routerfunctions; import org.springframework.web.reactive.function.server.serverresponse; /** * @author dalaoyang * @project springboot_learn * @package com.dalaoyang.router * @email yangyang@dalaoyang.cn * @date 2018/7/30 */ @configuration public class hirouter { @bean public routerfunction<serverresponse> routecity(hihandler hihandler) { return routerfunctions .route(requestpredicates.get("/hi") .and(requestpredicates.accept(mediatype.application_json)), hihandler::hi); } }
启动项目,通过控制台可以看到,两种方式的映射都被打印出来了,如图所示:
在浏览器访问,http://localhost:8080/hi,结果如图所示:
源码下载 :
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: SpringBoot使用JWT实现登录验证的方法示例
下一篇: 养成良好java代码编码规范