Spring Webflux 异步框架入门
spring-webflux 是Spring5提供的一个新的响应式Web框架。
spring-webflux上层支持两种开发模式:
- 类似于Spring WebMVC的基于注解(
@Controller
、@RequestMapping
)的开发模式; - Java 8 lambda 风格的函数式开发模式
鉴于大家都对springMVC非常了解的基础上,我就不以springMVC的注解的方式进行举例讲解了,
以下所有的例子都是以全新的Java 8 lambda 风格的函数式风格
1.Java依赖(maven)
<!-- spring-webflux --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- mybatis starter--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!-- PageHelper 分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <!-- thymeleaf 模版引擎 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- 热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <!-- mysql jdbc驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
2.RouterFunction注入代替springMVC的@RequestMapping注解
@Autowired private BannerHandler bannerHandler; @Bean public RouterFunction<ServerResponse> webFluxRoutesRegister(){ return RouterFunctions .route(RequestPredicates.GET("/banner/getList"), bannerHandler::getList)//查询 json响应 .andRoute(RequestPredicates.PUT("/banner/update"), bannerHandler::update)//更新 json响应 .andRoute(RequestPredicates.DELETE("/banner/deletes/{ids}"), bannerHandler::deletes)//删除 json响应 .andRoute(RequestPredicates.GET("/banner/init"), bannerHandler::init)//页面渲染 html响应 .andRoute(RequestPredicates.POST("/banner/upload"), bannerHandler::upload)//文件上传 json响应 .andRoute(RequestPredicates.GET("/banner/download"), bannerHandler::download);//文件下载 stream IO }
Handler代码:
@Component public class BannerHandler { @Autowired private BannerService bannerService; public Mono<ServerResponse> getList(ServerRequest request) { //获取请求参数 String page = request.queryParam("page").orElse("1"); String size = request.queryParam("rows").orElse("5"); DataGridVO<Banner> result = bannerService.getList(Integer.valueOf(page), Integer.valueOf(size)); return ServerResponse.ok().body(BodyInserters.fromObject(result)); } public Mono<ServerResponse> update(ServerRequest request) { //参数序列化为实体类进行更新 return request.bodyToMono(Banner.class).flatMap(banner -> { return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(bannerService.update(banner))); }); } public Mono<ServerResponse> deletes(ServerRequest request) { //获取路径中的参数作用等同于 @PathVariable String ids = request.pathVariable("ids"); Assert.hasText(ids, "ids不能为空"); return ServerResponse.ok().body(BodyInserters.fromObject(bannerService.deletes(ids.split(",")))); } public Mono<ServerResponse> init(ServerRequest request) { Map<String, Object> map = new HashMap<>(); map.put("name", "aqiu"); map.put("time", new Date()); List<String> list = new ArrayList<String>(); list.add("param1"); list.add("param2"); list.add("param3"); map.put("list", list); //返回thymeleaf模版页面 return ServerResponse.ok().render("index", map); } public Mono<ServerResponse> upload(ServerRequest request) { //获取文件参数 并进行存储 return request.multipartData().flatMap(map -> { map.forEach((k, v) -> { v.forEach(i -> { FilePart f = (FilePart) i; f.transferTo(new File("/tmp/" + f.filename())); }); }); return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(map.size())); }); } public Mono<ServerResponse> download(ServerRequest request) { //读取文件并包装为DataBuffer返回,spring-webflux会自动写入response File file = new File("/tmp/test.jpeg"); return ServerResponse.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.jpeg") .contentType(MediaType.IMAGE_JPEG).contentLength(file.length()) .body(BodyInserters.fromDataBuffers(Mono.create(r -> { DataBuffer buf = new DefaultDataBufferFactory().wrap(FileIOUtil.syncRead(file)); r.success(buf); return; }))); } }
thymeleaf 配置
demo over~
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #4f76cb }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #4e9192 }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo }
span.s1 { color: #000000 }
span.s2 { color: #009193 }
span.s3 { color: #4e9192 }
span.Apple-tab-span { white-space: pre }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo }