SpringBoot(七、sse,响应式编程)

Webflux

1、Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架

与Spring MVC不同,它不需要Servlet API,完全异步和非阻塞,并 通过Reactor项目实现Reactive Streams规范。

2、Flux和Mono

  • 1)简单业务而言:和其他普通对象差别不大,复杂请求业务,就可以提升性能
  • 2)通俗理解:
    • Mono 表示的是包含 0 或者 1 个元素的异步序列

      • mono->单一对象 User redis->用户ID-》唯一的用户Mono
    • Flux 表示的是包含 0 到 N 个元素的异步序列

      • flux->数组列表对象 List redis->男性用户->Flux
      • Flux 和 Mono 之间可以进行转换

3、Spring WebFlux有两种风格:基于功能和基于注解的。基于注解非常接近Spring MVC模型,如以下示例所示:

第一种:
@RestController 
@RequestMapping(“/ users”)
public  class MyRestController {
    @GetMapping(“/ {user}”)
    public Mono  getUser( @PathVariable Long user){
    }

    @GetMapping(“/ {user} / customers”)
    public Flux  getUserCustomers( @PathVariable Long user){
    }

    @DeleteMapping(“/ {user}”)
    public Mono  deleteUser( @PathVariable Long user){
    }
}
第二种: 路由配置与请求的实际处理分开
@Configuration
public  class RoutingConfiguration {
    @Bean
    public RouterFunction  monoRouterFunction(UserHandler userHandler){
        return route(GET( “/ {user}”).and(accept(APPLICATION_JSON)),userHandler :: getUser)
        .andRoute(GET(“/ {user} / customers”).and(accept(APPLICATION_JSON)),userHandler :: getUserCustomers)
        .andRoute(DELETE(“/ {user}”).and(accept(APPLICATION_JSON)),userHandler :: deleteUser);
    }

}

@Component
public class UserHandler {

    public Mono  getUser(ServerRequest请求){
                     // ...
    }

    public Mono  getUserCustomers(ServerRequest request){
                     // ...
    }

    public Mono  deleteUser(ServerRequest请求){
                     // ...
    }
}

4、Spring WebFlux应用程序不严格依赖于Servlet API,因此它们不能作为war文件部署,也不能使用src/main/webapp目录

5、可以整合多个模板引擎

除了REST Web服务外,您还可以使用Spring WebFlux提供动态HTML内容。Spring WebFlux支持各种模板技术,包括Thymeleaf,FreeMarker

基本使用

  • 添加依赖

替代spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-webflux

  • 控制器
@RestController
@RequestMapping("/api/v1/user")
public class UserController {

    @GetMapping("test")
    public Mono test() {
        return Mono.just("Hello");
    }

    //返回单个
    @GetMapping("getuser")
    public Mono getUser() {
        User user=new User();
        user.setAge(10);
        user.setName("zq");
//        Mono.justOrEmpty() 该方法代表有就返回否则返回null,一般使用这个
        return Mono.just(user);
    }


    //返回多个
    @GetMapping("getuserhaha")
    public Flux getUsersHa() {
        Map obj=new HashMap<>();
        for (int a=0;a<10;a++) {
            User user=new User();
            user.setAge(a);
            user.setName("zq"+a);
            obj.put(a,user);
        }
        return Flux.fromIterable(obj.values());
    }
    
    //响应是返回,每隔1秒返回一个,直到全部返回完全,只是一次网络请求
    @GetMapping(value = "getusers",produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
    public Flux getUsers() {
        Map obj=new HashMap<>();
        for (int a=0;a<10;a++) {
            User user=new User();
            user.setAge(a);
            user.setName("zq"+a);
            obj.put(a,user);
        }
        return Flux.fromIterable(obj.values()).delayElements(Duration.ofSeconds(1));
    }
}
  • 访问

http://127.0.0.1:8080/api/v1/user/getusers

WebClient(反应式客户端)

用于请求webflux服务端返回的数据,但是不常用

官网地址

@Test
    public void testHttp() {
        Mono body= WebClient.create().get().uri("http://127.0.0.1:8080/api/v1/user/getuser")
                .accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(String.class);
        System.out.println(body.block());
    }

SSE

服务端主动推送:SSE (Server Send Event)

  • html5新标准,用来从服务端实时推送数据到浏览器端,
  • 直接建立在当前http连接上,本质上是保持一个http长连接,轻量协议
  • 简单的服务器数据推送的场景,使用服务器推送事件

注意点:

需要把response的类型 改为 text/event-stream,才是sse的类型

控制器

@RequestMapping("/sse")
@RestController
public class SSEController {

    @RequestMapping(value = "getdata",produces = "text/event-stream;charset=UTF-8")
    public String push() {
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        return Math.random()+"\n\n";
    }
}

html文件




    
    
    
    Document


    
Test

说明:sse是建立连接不断开(长连接),然后客户端会自动请求,相比于长轮询效率更高;sse还有有断开重试的功能,简化版websocket

你可能感兴趣的:(SpringBoot(七、sse,响应式编程))