当前位置: 首页 > 知识库问答 >
问题:

Spring webflux:如何配置控制器和WebClient以像代理一样工作?

施华奥
2023-03-14

我需要一个在代理模式下工作的endpoint:将请求转发到外部REST API。目前我实现了这样的类,但它离理想还很远。

import java.net.URI;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

@RestController
public class ProxyController2 {

  private static final int OFFSET = 4;
  private static final String SCHEME = "http";
  private static final String HOTS = "127.0.0.1";
  private static final String PORT = "9090";

  @RequestMapping("/proxy/public/**")
  public Mono<String> publicProxy(ServerHttpRequest request) {
    HttpMethod httpMethod = request.getMethod();

    if (bodyRequired(httpMethod)) {
      return WebClient.create()
          .method(httpMethod)
          .uri(composeTargetUri(request))
          .headers(headers -> headers.addAll(request.getHeaders()))
          .body(BodyInserters.fromDataBuffers(request.getBody()))
          .retrieve()
          .bodyToMono(String.class);
    } else {
      return WebClient.create()
          .method(httpMethod)
          .uri(composeTargetUri(request))
          .headers(headers -> headers.addAll(request.getHeaders()))
          .retrieve()
          .bodyToMono(String.class);
    }
  }

  private URI composeTargetUri(ServerHttpRequest request) {
    return UriComponentsBuilder.newInstance()
        .scheme(SCHEME)
        .host(HOTS)
        .port(PORT)
        .path(getTargetPath(request))
        .build()
        .toUri();
  }

  private String getTargetPath(ServerHttpRequest request) {
    return request.getPath().pathWithinApplication()
        .subPath(OFFSET)
        .value();
  }

  private boolean bodyRequired(HttpMethod httpMethod) {
    return httpMethod == HttpMethod.DELETE || httpMethod == HttpMethod.POST
        || httpMethod == HttpMethod.PUT;
  }
}

它有一些缺点:
*它总是以字符串形式返回结果
*我们会丢失响应头
*我们失去响应状态(它会生成500条错误消息描述)。

你知道在spring webflux应用程序中创建代理控制器的好方法吗?

共有1个答案

邓欣可
2023-03-14

春云之门

构建在Spring生态系统之上的API网关,包括:Spring 5、Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API,并为它们提供跨领域的关注点,例如:安全性、监控/度量和弹性。

博士:Spring云网关

 类似资料:
  • 配置代理服务器能干嘛 NEI toolkit 提供了代理服务器的功能,帮助将接口代理到NEI官网或者特定的服务器上 将接口代理到NEI官网 开启该功能只需将server.config.js中的online设为true, 那么对Mock Server的所有请求都将会代理到NEI官网上,该模式也被称为在线模式。 启用在线模式可以减少执行nei update的操作,在频繁更改官网数据的情况下能够大幅加快

  • 我们将AWS RDS Aurora用于我们的应用程序,并使用read副本从数据库读取数据。 我们现在想要使用这个读取副本作为writer,这样我们也可以写入这个reader实例,并且数据将在它们之间同步。因此可以将其用作多主复制。 有没有办法做到这一点?

  • 问题内容: 我有 : (v2.4)在我服务器的端口80上,启用了 mod_proxy 和 mod_proxy_wstunnel 在同一服务器的端口3001上。 由于使用此处描述的方法,访问(使用端口80)将重定向到2 .。我已经在Apache配置中对此进行了设置: 它适用于除websocket部分之外的所有内容:不会像代理服务器那样传输。 访问上的页面时,我有: 问: 如何也使Apache代理We

  • 我有: > Apache 2.4在我服务器的80端口上,启用了mod_proxy和mod_proxy_wstunnel 节点.js 在同一服务器的端口 3001 上 访问<code>示例。com(带有端口80)重定向到2。这得益于具有以下Apache配置的此方法: 它适用于所有事情,除了websocket部分 :不是由代理传输的。 当我访问 上的页面时,我有: 问题:如何让Apache也代理Web

  • 除了websocket部分之外,不会像代理那样传输。 当我访问上的页面时,我有: 问题:如何使Apache代理也成为WebSockets?

  • 我正在使用一个功能组件,我需要能够使用componentDidMount()。我在网上发现,通过react钩子,可以将useEffect()用作功能组件中的componentDidMount()。然而,这并不像我想象的那样有效。我原以为在页面加载时会触发,但事实并非如此。有人知道如何让useEffect表现得像componentDidMount吗? 我试着只是简单地这样做,但它创建了一个无限循环,