Spring Boot – Как получить текущий порт
У меня есть приложение загрузки весны (с использованием встроенного tomcat 7), и я установил server.port = 0
в моих application.properties
чтобы у меня был случайный порт. После того, как сервер загрузился и запущен на порту, мне нужно получить порт, который был выбран.
Я не могу использовать @Value("$server.port")
потому что он равен нулю. Это, казалось бы, простая часть информации, поэтому почему я не могу получить доступ к ней из своего java-кода? Как я могу получить к нему доступ?
- Программно создать веб-сайт в IIS с помощью C # и установить номер порта
- На локальном хосте, как мне выбрать номер порта?
- Как запускать различные приложения на одном экземпляре Tomcat за разными портами?
- Как найти ansible порт?
- Как я могу обслуживать https и http для Jetty из одного порта?
- TCP: могут ли два разных сокета совместно использовать порт?
- Как несколько клиентов одновременно подключаются к одному порту, например 80, на сервере?
- Как изменить номер порта tomcat
- В чем разница между портом и сокетом?
- Сокеты: доступ к порталу через Java
- Как открыть определенный порт, такой как 9090 в Google Compute Engine
Возможно ли также получить доступ к порту управления, например:
@SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT) public class MyTest { @LocalServerPort int randomServerPort; @LocalManagementPort int randomManagementPort;
Spring’s Environment хранит эту информацию для вас.
@Autowired Environment environment; String port = environment.getProperty("local.server.port");
На @Value("${local.server.port}")
взгляд это выглядит так же, как и инъекция поля, аннотированного @Value("${local.server.port}")
(или @LocalServerPort
, который идентичен), в результате чего при запуске возникает отказ автоустройства, поскольку значение недоступно пока контекст не будет полностью инициализирован. Разница здесь в том, что этот вызов неявно делается в бизнес-логике времени выполнения, а не вызван при запуске приложения, и, следовательно, «ленивый выбор» порта разрешает нормально.
Спасибо @Dirk Lachowski за то, что он указал мне в правильном направлении. Решение не так элегантно, как мне бы хотелось, но я получил его работу. Читая весенние документы, я могу прослушивать EmbeddedServletContainerInitializedEvent и получать порт после запуска и запуска сервера. Вот как это выглядит:
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class MyListener implements ApplicationListener { @Override public void onApplicationEvent(final EmbeddedServletContainerInitializedEvent event) { int thePort = event.getEmbeddedServletContainer().getPort(); } }
Вы можете получить порт, который используется встроенным экземпляром Tomcat во время тестов, введя значение local.server.port как таковое:
// Inject which port we were assigned @Value("${local.server.port}") int port;
Начиная с 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; // ... }
Ни одно из этих решений не работало для меня. Мне нужно было знать порт сервера при построении компонента конфигурации Swagger. Использование 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 } }
В этом примере используется автоматическая настройка Spring Boot и JAX-RS (а не Spring MVC).
Просто так, что другие, которые настроили свои приложения, такие как мои, выиграли от того, что я прошел …
Ни один из вышеперечисленных решений не работал для меня, потому что у меня есть каталог ./config
только под моей проектной базой с 2 файлами:
application.properties
application-dev.properties
В application.properties
меня есть:
spring.profiles.active = dev # set my default profile to 'dev'
В application-dev.properties
меня есть:
server_host = localhost server_port = 8080
Это так, когда я запускаю свою жирную банку из CLI, файлы *.properties
будут считаны из ./config
и все это хорошо.
Ну, оказывается, что эти файлы свойств полностью переопределяют параметр webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
в @SpringBootTest
в моих спецификациях Spock. Независимо от того, что я пробовал, даже с установкой webEnvironment
в RANDOM_PORT
Spring всегда RANDOM_PORT
встроенный контейнер Tomcat на порт 8080 (или любое RANDOM_PORT
значение, которое я установил бы в своих файлах ./config/*.properties
).
Единственный способ, которым я смог преодолеть это, заключался в добавлении явных properties = "server_port=0"
в аннотацию @SpringBootTest
в моих спецификациях интеграции Spock:
@SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "server_port=0")
Затем, и только тогда весна наконец начала разворачивать Tomcat на случайном порту. ИМХО это ошибка весны тестирования Spring, но я уверен, что у них будет собственное мнение об этом.
Надеюсь, это помогло кому-то.