gpt4 book ai didi

java - Zuul代理-如何根据请求路径将请求转发到服务

转载 作者:行者123 更新时间:2023-12-01 19:26:37 33 4
gpt4 key购买 nike

问题

如何在Spring Cloud应用程序中转发请求?我需要根据 uri 的部分将请求转发到其他服务。

例如

  • HTTP GET http://user-application/api/users,返回用户 JSON。
  • HTTP GET http://user-application/api/proxy/jobs-application/api/jobs,返回作业 JSON,但此请求应转发到另一个应用程序:HTTP GET http://jobs-application/api/jobs

    • 允许使用任何 HTTP 方法,而不仅仅是 GET

上下文

我有一个 SpringBoot 应用程序,用户应用程序,它具有返回数据的 REST 端点。

例如 GET http://user-application/api/users 将以 JSON 格式返回用户。

用户应用程序还有一个 HTTP 端点,该端点应将请求转发到其他应用程序 - 让我们将其中一个称为作业应用程序

例如,此端点为 HTTP {ANY_METHOD}/api/proxy/{dynamic-service}/{dynamic-path}获取http://user-application/api/proxy/jobs-application/api/jobs

请注意,初始请求发送至用户应用程序,然后转发至职位应用程序

方法

我提出了一些我认为的方法。也许您过去做过类似的事情,所以您可以分享您的经验。或者甚至改进我的一种方法。

ProxyController 方法

我将在用户应用程序中创建一个ProxyController,并映射/proxy

@Controller
@RequestMaping("/proxy/**")
ProxyController

public void proxy(final HttpServletRequest request, HttpResponse response) {
final String requestUri = request.getRequestUri();
if (!requestUri.startsWith("/api/proxy/")) {
return null; // Do not proxy
}

final int proxyIndex = "/api/proxy/".lenght(); // Can be made a constant
final String proxiedUrl = requestUri.subString(proxyIndex, requestUri.lenght());

final Optional<String> payload = retrievePayload(request);
final Headers headers = retrieveHeaders(request);

final HttpRequest proxyRequest = buildProxyRequest(request, headers);
payload.ifPresent(proxyRequest::setPayload);
final HttpResponse proxyResponse = httpClient.execute(proxyRequest)
pdateResponse(response, proxyResponse);
}

这种方法的问题是,我必须编写大量代码来构建代理请求,以检查它是否有有效负载,如果有,请将其复制到代理请求中,然后将 header 、cookie 等复制到代理请求中,将 HTTP 动词复制到代理请求中。然后,当我收到代理响应时,我必须将其详细信息填充到响应中。

Zuul方法

我受到 ZuulFilters 的启发:

@Component
public class ProxyFilter extends ZuulFilter {

private static final String PROXY_PART = "/api/proxy";
private static final int PART_LENGTH = PROXY_PART.length();

@Autowired
public ProxyFilter() {
}

@Override
public boolean shouldFilter() {
final RequestContext context = RequestContext.getCurrentContext();
final String requestURI = retrieveRequestUri(context);
return requestURI.startsWith(PROXY_PART);
}

@Override
public Object run() {
final RequestContext context = RequestContext.getCurrentContext();
final String requestURI = retrieveRequestUri(context);
final String forwardUri = requestURI.substring(PART_LENGTH);
context.setRouteHost(buildUrl(forwardUri));

return null;
}

@Override
public String filterType() {
return "proxy";
}

@Override
public int filterOrder() {
return 0;
}

private String retrieveRequestUri(final RequestContext context) {
final HttpServletRequest request = context.getRequest();
return request.getRequestURI();
}

private URL buildUrl(final String uri) {
try {
return new URL(uri);
} catch (MalformedURLException e) {
throw new RuntimeException(String.format("Failed to forward request uri %s}.", uri), e);
}
}
}

这段代码让我可以更轻松地转发请求。但是,我们还在 Spring Cloud Zuul 中开箱即用地使用客户端负载均衡器 Ribbon 和断路器 Hystrix。如何启用这些功能?它们是否会在 context.setRouteHost(forwardUrl);

中立即启用

最佳答案

我想添加另一种方法,也许它也可行。

用于配置 Zuul 代理方法的静态 application.yml 文件

这种方法不需要动态 Zuul 过滤器。

应用程序.yml

zuul:
routes:
user-application:
path: /api/users/**
serviceId: user-service
stripPrefix: false
sensitiveHeaders:

# I have to define all other services similarly.

jobs-application:
path: /api/proxy/jobs/**
serviceId: jobs-application
stripPrefix: true
sensitiveHeaders:

只有当我在部署用户应用程序之前知道客户需要调用的所有服务时,它才会起作用。如果动态添加新应用程序怎么办?然后我将不得不更新配置。

关于java - Zuul代理-如何根据请求路径将请求转发到服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59308615/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com