Spring Boot Webflux 【Quickstart】

父工程pom.xml

<?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.example</groupId>
    <artifactId>Spring-WebFlux-Demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>DemoServer</module>
        <module>DemoClient</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--将项目打包成可执行jar用到的插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

 

DemoServer

pom.xml

<?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">
    <parent>
        <artifactId>Spring-WebFlux-Demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>DemoServer</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

ServerApp.java 

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ServerApp {
    public static void main(String[] args) {
        System.setProperty("server.port","16000");
        SpringApplication.run(ServerApp.class, args);
    }
}

DemoOldController.java

package com.example.mvc;

import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/old")
public class DemoOldController {

    // http://127.0.0.1:16000/old/get
    @GetMapping("/get")
    public Mono<String> getFunction() {
        return Mono.just("GET|Old|Msg: Hello World");
    }

    // http://127.0.0.1:16000/old/post
    @PostMapping("/post")
    public Mono<String> postFunction(@RequestBody String body){
        System.out.println(body);
        return Mono.just("POST|Old|Msg: " + body);
    }
}

DemoHandlers.java

package com.example.webflux;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.util.Optional;

@Component
public class DemoHandlers {

    private static final String Msg = "Hello World!";

    // http://127.0.0.1:16000/new/get
    public Mono<ServerResponse> getFunction(ServerRequest request){

        //REST 方式获取
        //路由url /new/get/{data}
        //String data = request.pathVariable("data");

        //请求的url中传参, 例如: /new/get?data=xxx
        Optional<String> date = request.queryParam("data");
        String retValue = "GET|New|Msg: " +  date.orElse(Msg);

        return ServerResponse.ok()
                .contentType(MediaType.TEXT_PLAIN)
                .bodyValue(retValue);
    }

    // http://127.0.0.1:16000/new/post
    public Mono<ServerResponse> postFunction(ServerRequest request){
        //如果请求体中为空时,返回默认值
        Mono<String> stringMono = request.bodyToMono(String.class).defaultIfEmpty(Msg);

        //这样获取请求中的数据会报错
        //String reqBody = stringMono.block();

        //如果需要对Mono中的数据进行处理,就需要使用flatMap
        return stringMono.flatMap((value)->{

            return ServerResponse.ok()
                    .contentType(MediaType.TEXT_PLAIN)
                    .bodyValue("POST|New|Msg: " +  value);
        });
    }
}

Routers.java

package com.example.webflux;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.*;

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;

@Configuration
public class Routers {

    @Bean
    public RouterFunction<ServerResponse> routerFunction(DemoHandlers demoHandlers) {

        //统一的前缀,相当于mvc中在类的上面加@RequestMapping("/new")
        RouterFunction<ServerResponse> routeFormat1 = RouterFunctions
                .route()
                .nest(RequestPredicates.path("/new"), () ->
                        RouterFunctions
                                .route(GET("/get"), demoHandlers::getFunction)
                                .andRoute(POST("/post"), demoHandlers::postFunction)
                ).build();

        //统一前缀的第二张方式
        RouterFunction<ServerResponse> routeFormat2 = RouterFunctions
                .route()
                .nest(RequestPredicates.path("/new"), () ->
                        RouterFunctions.route()
                                .GET("/get", demoHandlers::getFunction)
                                .POST("/post", demoHandlers::postFunction)
                                .build())
                .build();


        //每个url中都自己写全
        RouterFunction<ServerResponse> routeFormat3 = RouterFunctions
                .route()
                .GET("/new/get", demoHandlers::getFunction)
                .POST("/new/post", demoHandlers::postFunction)
                .build();

        return routeFormat1;
    }
}

 

DemoClient

pom.xml

<?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">
    <parent>
        <artifactId>Spring-WebFlux-Demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>DemoClient</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

ClientApp.java

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ClientApp {
    public static void main(String[] args) {
        System.setProperty("server.port","16001");
        SpringApplication.run(ClientApp.class, args);
    }
}

DemoController.java

package com.example;

import io.netty.handler.codec.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufMono;
import reactor.netty.http.client.HttpClient;

@RestController
@RequestMapping("/demo")
public class DemoController {

    /** WebClient 是 web flux提供的http客户端   */
    private static final WebClient webClient = WebClient.create();

    /** HttpClient 是 reactor.-netty提供的http客户端   */
    private static final HttpClient httpClient = HttpClient.create();

    private static final String URL_PREFIX = "http://127.0.0.1:16000";

    private static final String HelloWorld = "hello world";

    /**
     *
     * http://127.0.0.1:16001/demo/webclient/get
     */
    @RequestMapping("/webclient/get")
    public Mono<String> webClientGet() {
        return webClient.get()
                .uri(URL_PREFIX + "/old/get")
                .retrieve()//发起请求并获得响应
                .bodyToMono(String.class);//将请求结果需要处理为String,并包装为Reactor的Mono对象
    }

    /**
     * http://127.0.0.1:16001/demo/webclient/post
    */
    @RequestMapping("/webclient/post")
    public Mono<String> webClientPost() {

        return webClient.post()
                .uri(URL_PREFIX + "/old/post")
                .contentType(MediaType.TEXT_PLAIN)
                .bodyValue(HelloWorld)
                .retrieve()//发起请求并获得响应
                .bodyToMono(String.class);//将请求结果需要处理为String,并包装为Reactor的Mono对象
    }

    /**
     * http://127.0.0.1:16001/demo/httpclient/get
     */
    @RequestMapping("/httpclient/get")
    public Flux<String> httpClientGet() {
        return httpClient.request(HttpMethod.GET)
                .uri(URL_PREFIX + "/new/get")
                .responseContent() //读取响应体
                .asString();
    }

    /**
     * http://127.0.0.1:16001/demo/httpclient/post
     */
    @RequestMapping("/httpclient/post")
    public Flux<String> httpClientPost() {
        return httpClient.request(HttpMethod.POST)
                .uri(URL_PREFIX + "/new/post")
                .send(ByteBufMono.fromString(Mono.just(HelloWorld)))
                .responseContent()
                .asString();
    }
}

 

官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#spring-webflux

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值