Spring Webflux 响应式框架入门

spring-webflux 是Spring5提供的一个新的响应式Web框架。

spring-webflux上层支持两种开发模式: 

  • 类似于Spring WebMVC的基于注解(@Controller@RequestMapping)的开发模式;
  • Java 8 lambda 风格的函数式开发模式

鉴于大家都对springMVC非常了解的基础上,我就不以springMVC的注解的方式进行举例讲解了,

以下所有的例子都是以全新的Java 8 lambda 风格的函数式风格

1.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~

 

 

 

 

posted @ 2018-08-21 17:39  阿秋秋  阅读(6285)  评论(0编辑  收藏  举报