如何获取Quarkus应用运行时的实时HTTP端口值?
解决Quarkus运行时获取真实HTTP端口的问题
问题说明
在Quarkus服务里,端点需要返回同服务内其他端点的URL,但直接注入quarkus.http.port或通过ConfigProvider.getConfig()拿到的端口始终是配置默认值(比如8080)——哪怕测试环境实际跑的是8081,导致测试时没法用返回的URL发起后续请求。虽然临时加%test.quarkus.http.port=8081能解决,但更希望Quarkus能自动返回任意环境下的真实HTTP地址。
有效解决方案
别直接读配置属性,改用Quarkus提供的运行时对象来获取真实端口,具体两种方式:
1. 注入HttpServerConfiguration
在资源类里注入HttpServerConfiguration,它会保存运行时的真实端口和主机信息:
import io.quarkus.runtime.configuration.HttpServerConfiguration; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @Path("/demo") public class DemoResource { @Inject HttpServerConfiguration serverConfig; @GET @Path("/target-url") public String getTargetEndpointUrl() { return String.format("http://%s:%d/internal/endpoint", serverConfig.host, serverConfig.port); } }
2. 使用RuntimeValue获取动态端口
如果测试环境是Quarkus自动分配的随机端口,注入RuntimeValue能直接拿到实时值:
import io.quarkus.runtime.RuntimeValue; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @Path("/demo") public class DemoResource { @Inject RuntimeValue<Integer> httpPort; @Inject RuntimeValue<String> httpHost; @GET @Path("/target-url") public String getTargetEndpointUrl() { return String.format("http://%s:%d/internal/endpoint", httpHost.getValue(), httpPort.getValue()); } }
测试环境验证
在QuarkusTest里,还能通过RestAssured的getPort()方法拿到当前测试端口,用来校验返回的URL是否正确:
import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.containsString; @QuarkusTest public class DemoResourceTest { @Test public void testTargetUrl() { int currentTestPort = given().getPort(); given() .when().get("/demo/target-url") .then() .statusCode(200) .body(containsString(String.format(":%d/", currentTestPort))); } }
原方法失效原因
quarkus.http.port是配置的默认值,当Quarkus在测试环境自动分配端口、或是动态修改端口时,这个配置值不会同步更新。而HttpServerConfiguration和RuntimeValue是Quarkus运行时动态维护的对象,会实时持有服务实际使用的端口信息。
内容的提问来源于stack exchange,提问作者Joost den Boer
相关产品推荐
相关产品推荐

