Tuc*_*ker 62 port spring embedded-tomcat-7 spring-boot
我有一个spring boot应用程序(使用嵌入式tomcat 7),我已经设置server.port = 0了我的application.properties所以我可以有一个随机端口.服务器启动并在端口上运行后,我需要能够获得所选的端口.
我不能使用,@Value("$server.port")因为它是零.这是一个看似简单的信息,为什么我不能从我的java代码中访问它?我该如何访问它?
小智 73
是否也可以以类似的方式访问管理端口,例如:
@SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT)
public class MyTest {
@LocalServerPort
int randomServerPort;
@LocalManagementPort
int randomManagementPort;
Run Code Online (Sandbox Code Playgroud)
hen*_*nnr 58
Spring的环境为您提供此信息.
@Autowired
Environment environment;
String port = environment.getProperty("local.server.port");
Run Code Online (Sandbox Code Playgroud)
从表面上看,这看起来与注入注释的字段@Value("${local.server.port}")(或@LocalServerPort相同的)相同,从而在启动时抛出自动装配失败,因为在完全初始化上下文之前该值不可用.这里的区别在于,此调用隐式在运行时业务逻辑中进行,而不是在应用程序启动时调用,因此端口的"lazy-fetch"可以解决.
Tuc*_*ker 21
感谢@Dirk Lachowski将我指向了正确的方向.解决方案并不像我希望的那样优雅,但我得到了它的工作.阅读spring docs,我可以监听EmbeddedServletContainerInitializedEvent并在服务器启动并运行后获取端口.这是它的样子 -
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyListener implements ApplicationListener<EmbeddedServletContainerInitializedEvent> {
@Override
public void onApplicationEvent(final EmbeddedServletContainerInitializedEvent event) {
int thePort = event.getEmbeddedServletContainer().getPort();
}
}
Run Code Online (Sandbox Code Playgroud)
Jac*_*man 13
就像其他配置了我的应用程序的人一样受益于我所经历的......
上述解决方案中没有工作对我来说,因为我有一个./config目录不到我的项目基地,2个文件:
application.properties
application-dev.properties
在application.properties我有:
spring.profiles.active = dev # set my default profile to 'dev'
Run Code Online (Sandbox Code Playgroud)
在application-dev.properties我有:
server_host = localhost
server_port = 8080
Run Code Online (Sandbox Code Playgroud)
这是当我从CLI运行我的胖罐时,*.properties文件将从./config目录中读取,一切都很好.
好吧,事实证明这些属性文件完全覆盖了我的Spock规范中的webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT设置 @SpringBootTest.无论我尝试什么,即使webEnvironment设置为RANDOM_PORTSpring,也总是在端口8080上启动嵌入式Tomcat容器(或者我在./config/*.properties文件中设置的任何值).
我能够克服这个问题的唯一方法是在我的Spock集成规范中添加一个明确properties = "server_port=0"的@SpringBootTest注释:
@SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "server_port=0")
Run Code Online (Sandbox Code Playgroud)
然后,只有这样,Spring终于开始在随机端口上启动Tomcat.恕我直言这是一个Spring测试框架错误,但我相信他们对此有自己的看法.
希望这有助于某人.
bsy*_*syk 12
您可以通过注入local.server.port值来获取测试期间嵌入式Tomcat实例正在使用的端口:
// Inject which port we were assigned
@Value("${local.server.port}")
int port;
Run Code Online (Sandbox Code Playgroud)
jab*_*bal 12
从Spring Boot 1.4.0开始,您可以在测试中使用它:
import org.springframework.boot.context.embedded.LocalServerPort;
@SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT)
public class MyTest {
@LocalServerPort
int randomPort;
// ...
}
Run Code Online (Sandbox Code Playgroud)
在 Spring Boot 2 之后,发生了很多变化。上面给出的答案在 Spring Boot 2 之前有效。现在,如果您使用服务器端口的运行时参数运行您的应用程序,那么您将只能获得application.properties文件中@Value("${server.port}")提到的静态值。现在要获取服务器运行的实际端口,请使用以下方法:
@Autowired
private ServletWebServerApplicationContext server;
@GetMapping("/server-port")
public String serverPort() {
return "" + server.getWebServer().getPort();
}
Run Code Online (Sandbox Code Playgroud)
此外,如果您将应用程序用作负载平衡的 Eureka/Discovery 客户端RestTemplate或WebClient,上述方法将返回确切的端口号。
这些解决方案都不适合我.构建Swagger配置bean时,我需要知道服务器端口.使用ServerProperties为我工作:
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.ApplicationPath;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.jaxrs.listing.ApiListingResource;
import io.swagger.jaxrs.listing.SwaggerSerializers;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
@Component
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig
{
@Inject
private org.springframework.boot.autoconfigure.web.ServerProperties serverProperties;
public JerseyConfig()
{
property(org.glassfish.jersey.server.ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
}
@PostConstruct
protected void postConstruct()
{
// register application endpoints
registerAndConfigureSwaggerUi();
}
private void registerAndConfigureSwaggerUi()
{
register(ApiListingResource.class);
register(SwaggerSerializers.class);
final BeanConfig config = new BeanConfig();
// set other properties
config.setHost("localhost:" + serverProperties.getPort()); // gets server.port from application.properties file
}
}
Run Code Online (Sandbox Code Playgroud)
此示例使用Spring Boot自动配置和JAX-RS(不是Spring MVC).
| 归档时间: |
|
| 查看次数: |
72508 次 |
| 最近记录: |