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~

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM