gpt4 book ai didi

spring-boot - 有没有办法为 Spring HATEOAS `ControllerLinkBuilder` 设置主机和端口?

转载 作者:行者123 更新时间:2023-12-04 14:44:52 24 4
gpt4 key购买 nike

Spring HATEOAS 提供了得心应手的ControllerLinkBuilder创建指向 Controller 方法的链接,这些链接将作为 href 添加到返回给客户端的 JSON/XML 中。例如:

resource.add(linkTo(methodOn(FooController.class)
.findFoo(entity.getClient().getId()))
.withRel("show"));

... 可能生成 JSON 有点像:
{
"name":"foo",
"links":[
{"rel":"show","href":"http://111.11.11.111:28080/foos/1"}
]
}

然而...

我倾向于通过反向代理访问我的服务。我想大多数人可能会这样做。这让我可以在不同的端口上运行多个服务,但让我可以通过相同的基本 URL 访问它们。不幸的是,通过代理访问意味着 Spring HATEOAS 生成的 URL 不是访问资源的有效 URL。

现在我可以对链接进行硬编码,但这相当脆弱。拥有 ControllerLinkBuilder基于我的 Controller 生成 URL @RequestMapping配置对我来说很有值(value),因为它避免了我的链接与现实不同步的风险。

所以我想知道是否有一个属性可以用来强制主机和端口值。我正在使用 Spring Boot,所以理想情况下我可以添加到 application.properties 的属性每个环境中的文件。

笔记:

由于这个问题似乎是由 Spring 中的一个错误引起的,我可能应该指出我正在使用 Spring Boot 1.0.2.RELEASE。

最佳答案

对我最初提出的问题的纯粹回答似乎涉及编写我自己的 ControllerLinkBuilder可以选择根据我设置的环境变量构建 URL 的实现。我可以这样做。

但是,我试图强制 URL 的原因是 ControllerLinkBuilder 中存在一个错误。 .值得注意的是,这个bug是从ServletUriComponentsBuilder复制的代码中的一个bug。 .

String scheme = request.getScheme();

// The port number retrieved here is the port set by server.port
int port = request.getServerPort();
String host = request.getServerName();

String header = request.getHeader("X-Forwarded-Host");

if (StringUtils.hasText(header)) {
String[] hosts = StringUtils.commaDelimitedListToStringArray(header);
String hostToUse = hosts[0];
if (hostToUse.contains(":")) {
String[] hostAndPort = StringUtils.split(hostToUse, ":");
host = hostAndPort[0];

// Note that the port is set if there is a ":" in the address.
port = Integer.parseInt(hostAndPort[1]);
}
else {
host = hostToUse;
}
}

ServletUriComponentsBuilder builder = new ServletUriComponentsBuilder();
builder.scheme(scheme);
builder.host(host);

// Here lies the bug...
if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443)) {
builder.port(port);
}

基本上,端口仅在 server.port 时设置不是 80 或 443,而不是基于用于请求的端口。这意味着如果 X-Forwarded-Host正在为方案使用默认端口(因此在“:”之后没有任何内容),则将使用应用程序端口而不是默认端口。

关于spring-boot - 有没有办法为 Spring HATEOAS `ControllerLinkBuilder` 设置主机和端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24179807/

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