欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot2使用WebFlux函数式编程的方法

程序员文章站 2024-02-21 09:02:46
本文只是简单使用springboot2使用webflux的函数式编程简单使用,后续会继续写关于webflux相关的文章。 最近一直在研究webflux,后续会陆续出一些相...

本文只是简单使用springboot2使用webflux的函数式编程简单使用,后续会继续写关于webflux相关的文章。

最近一直在研究webflux,后续会陆续出一些相关的文章。

首先看一下srping官网上的一张图,对比一下springmvc和spring webflux,如图:

SpringBoot2使用WebFlux函数式编程的方法

在查看一下webflux的官方文档:,webflux提供了函数式编程,本文简单介绍一下webflux函数式编程简单使用。

新建项目

创建一个项目,pom文件中引入webflux依赖,完整pom文件如下:

<?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.dalaoyang</groupid>
  <artifactid>springboot2_webflux</artifactid>
  <version>0.0.1-snapshot</version>
  <packaging>jar</packaging>

  <name>springboot2_webflux</name>
  <description>springboot2_webflux</description>

  <parent>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-parent</artifactid>
    <version>2.0.3.release</version>
    <relativepath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceencoding>utf-8</project.build.sourceencoding>
    <project.reporting.outputencoding>utf-8</project.reporting.outputencoding>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter</artifactid>
    </dependency>

    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-test</artifactid>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-webflux</artifactid>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-maven-plugin</artifactid>
      </plugin>
    </plugins>
  </build>


</project>

首先试试引入webflux依赖之后,springmvc方式是否还能使用,新建一个hellocontroller,完整代码如下,执行后发现,是可以正常执行访问的,这其实就是我们所说的注解式编程。

package com.dalaoyang.controller;

import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;

/**
 * @author dalaoyang
 * @project springboot_learn
 * @package com.dalaoyang.controller
 * @email yangyang@dalaoyang.cn
 * @date 2018/7/30
 */
@restcontroller
public class hellocontroller {

  @getmapping("hello")
  public string hello(){
    return "hello this is springwebflux";
  }
}

结果如图:

SpringBoot2使用WebFlux函数式编程的方法

接下来使用函数式编程,首先查阅一下官方文档,如图:

SpringBoot2使用WebFlux函数式编程的方法

我们需要创建一个handlerfunction返回值为mono,新建一个hihandler,里面写一个方法hi,完整代码如下:

package com.dalaoyang.handler;
import org.springframework.http.mediatype;
import org.springframework.stereotype.component;
import org.springframework.web.reactive.function.bodyinserters;
import org.springframework.web.reactive.function.server.serverrequest;
import org.springframework.web.reactive.function.server.serverresponse;
import reactor.core.publisher.mono;


/**
 * @author dalaoyang
 * @project springboot_learn
 * @package com.dalaoyang.handler
 * @email yangyang@dalaoyang.cn
 * @date 2018/7/30
 */
@component
public class hihandler {


  public mono<serverresponse> hi(serverrequest request) {
    return serverresponse.ok().contenttype(mediatype.application_json)
        .body(bodyinserters.fromobject("hi , this is springwebflux"));
  }
}

其中serverresponse是相应的封装对象,下面是它的源码,其中包含了响应状态,响应头等等,代码如下:

package org.springframework.web.reactive.function.server;

import java.net.uri;
import java.time.zoneddatetime;
import java.util.list;
import java.util.map;
import java.util.set;
import java.util.function.bifunction;
import java.util.function.consumer;
import org.reactivestreams.publisher;
import org.springframework.core.parameterizedtypereference;
import org.springframework.http.cachecontrol;
import org.springframework.http.httpheaders;
import org.springframework.http.httpmethod;
import org.springframework.http.httpstatus;
import org.springframework.http.mediatype;
import org.springframework.http.responsecookie;
import org.springframework.http.codec.httpmessagewriter;
import org.springframework.http.server.reactive.serverhttpresponse;
import org.springframework.util.multivaluemap;
import org.springframework.web.reactive.function.bodyinserter;
import org.springframework.web.reactive.result.view.viewresolver;
import org.springframework.web.server.serverwebexchange;
import reactor.core.publisher.mono;

public interface serverresponse {
  httpstatus statuscode();

  httpheaders headers();

  multivaluemap<string, responsecookie> cookies();

  mono<void> writeto(serverwebexchange var1, serverresponse.context var2);

  static serverresponse.bodybuilder from(serverresponse other) {
    return new defaultserverresponsebuilder(other);
  }

  static serverresponse.bodybuilder status(httpstatus status) {
    return new defaultserverresponsebuilder(status);
  }

  static serverresponse.bodybuilder status(int status) {
    return new defaultserverresponsebuilder(status);
  }

  static serverresponse.bodybuilder ok() {
    return status(httpstatus.ok);
  }

  static serverresponse.bodybuilder created(uri location) {
    serverresponse.bodybuilder builder = status(httpstatus.created);
    return (serverresponse.bodybuilder)builder.location(location);
  }

  static serverresponse.bodybuilder accepted() {
    return status(httpstatus.accepted);
  }

  static serverresponse.headersbuilder<?> nocontent() {
    return status(httpstatus.no_content);
  }

  static serverresponse.bodybuilder seeother(uri location) {
    serverresponse.bodybuilder builder = status(httpstatus.see_other);
    return (serverresponse.bodybuilder)builder.location(location);
  }

  static serverresponse.bodybuilder temporaryredirect(uri location) {
    serverresponse.bodybuilder builder = status(httpstatus.temporary_redirect);
    return (serverresponse.bodybuilder)builder.location(location);
  }

  static serverresponse.bodybuilder permanentredirect(uri location) {
    serverresponse.bodybuilder builder = status(httpstatus.permanent_redirect);
    return (serverresponse.bodybuilder)builder.location(location);
  }

  static serverresponse.bodybuilder badrequest() {
    return status(httpstatus.bad_request);
  }

  static serverresponse.headersbuilder<?> notfound() {
    return status(httpstatus.not_found);
  }

  static serverresponse.bodybuilder unprocessableentity() {
    return status(httpstatus.unprocessable_entity);
  }

  public interface context {
    list<httpmessagewriter<?>> messagewriters();

    list<viewresolver> viewresolvers();
  }

  public interface bodybuilder extends serverresponse.headersbuilder<serverresponse.bodybuilder> {
    serverresponse.bodybuilder contentlength(long var1);

    serverresponse.bodybuilder contenttype(mediatype var1);

    serverresponse.bodybuilder hint(string var1, object var2);

    <t, p extends publisher<t>> mono<serverresponse> body(p var1, class<t> var2);

    <t, p extends publisher<t>> mono<serverresponse> body(p var1, parameterizedtypereference<t> var2);

    mono<serverresponse> syncbody(object var1);

    mono<serverresponse> body(bodyinserter<?, ? super serverhttpresponse> var1);

    mono<serverresponse> render(string var1, object... var2);

    mono<serverresponse> render(string var1, map<string, ?> var2);
  }

  public interface headersbuilder<b extends serverresponse.headersbuilder<b>> {
    b header(string var1, string... var2);

    b headers(consumer<httpheaders> var1);

    b cookie(responsecookie var1);

    b cookies(consumer<multivaluemap<string, responsecookie>> var1);

    b allow(httpmethod... var1);

    b allow(set<httpmethod> var1);

    b etag(string var1);

    b lastmodified(zoneddatetime var1);

    b location(uri var1);

    b cachecontrol(cachecontrol var1);

    b varyby(string... var1);

    mono<serverresponse> build();

    mono<serverresponse> build(publisher<void> var1);

    mono<serverresponse> build(bifunction<serverwebexchange, serverresponse.context, mono<void>> var1);
  }
}

在回过头了看上面官方文档的图片,还需要配置一个路由来类似@requestmapping的功能,通过routerfunctions.route(requestpredicate, handlerfunction)提供了一个路由器函数默认实现,新建一个hirouter,代码如下:

package com.dalaoyang.router;

import com.dalaoyang.handler.hihandler;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.http.mediatype;
import org.springframework.web.reactive.function.server.requestpredicates;
import org.springframework.web.reactive.function.server.routerfunction;
import org.springframework.web.reactive.function.server.routerfunctions;
import org.springframework.web.reactive.function.server.serverresponse;
/**
 * @author dalaoyang
 * @project springboot_learn
 * @package com.dalaoyang.router
 * @email yangyang@dalaoyang.cn
 * @date 2018/7/30
 */
@configuration
public class hirouter {
  @bean
  public routerfunction<serverresponse> routecity(hihandler hihandler) {
    return routerfunctions
        .route(requestpredicates.get("/hi")
                .and(requestpredicates.accept(mediatype.application_json)),
            hihandler::hi);
  }
}

启动项目,通过控制台可以看到,两种方式的映射都被打印出来了,如图所示:

SpringBoot2使用WebFlux函数式编程的方法

在浏览器访问,http://localhost:8080/hi,结果如图所示:

SpringBoot2使用WebFlux函数式编程的方法

源码下载 :

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。