J'ai une application de démarrage à ressort (en utilisant le tomcat intégré 7), et je l'ai défini server.port = 0
dans mon application.properties
pour pouvoir avoir un port aléatoire. Une fois que le serveur est démarré et fonctionne sur un port, je dois pouvoir obtenir le port qui a été choisi.
Je ne peux pas utiliser @Value("$server.port")
car c'est zéro. C'est une information apparemment simple, alors pourquoi ne puis-je pas y accéder à partir de mon code java? Comment puis-je y accéder?
Réponses:
Est-il également possible d'accéder au port de gestion d'une manière similaire, par exemple:
@SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT) public class MyTest { @LocalServerPort int randomServerPort; @LocalManagementPort int randomManagementPort;
la source
@LocalServerPort
est juste un raccourci pour@Value("${local.server.port}")
.Spring's Environment détient ces informations pour vous.
@Autowired Environment environment; String port = environment.getProperty("local.server.port");
En apparence, cela semble identique à l'injection d'un champ annoté
@Value("${local.server.port}")
(ou@LocalServerPort
, qui est identique), dans lequel un échec de câblage automatique est déclenché au démarrage car la valeur n'est pas disponible tant que le contexte n'est pas complètement initialisé. La différence ici est que cet appel est implicitement effectué dans la logique métier d'exécution plutôt qu'appelé au démarrage de l'application, et par conséquent, le «lazy-fetch» du port résout ok.la source
environment.getProperty("server.port")
n'a pas fonctionné pour moi .Merci à @Dirk Lachowski de m'avoir orienté dans la bonne direction. La solution n'est pas aussi élégante que je l'aurais souhaité, mais je l'ai fait fonctionner. En lisant la documentation du printemps, je peux écouter sur l'Event EmbeddedServletContainerInitializedEvent et obtenir le port une fois que le serveur est opérationnel. Voici à quoi ça ressemble -
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(); } }
la source
PortProvider
et en fournissant unegetPort()
méthode. J'ai câblé automatiquement mon entréePortProvider
au contrôleur nécessitant le port, et lorsque ma logique métier a été appeléeportProvider.getPort()
, le port d'exécution a été renvoyé.EmbeddedServletContainerInitializedEvent
, mais il existe une classe similaire appeléeServletWebServerInitializedEvent
qui a une.getWebServer()
méthode. Cela vous donnera au moins le port que Tomcat écoute.Juste pour que d'autres qui ont configuré leurs applications comme la mienne bénéficient de ce que j'ai vécu ...
Aucune des solutions ci-dessus n'a fonctionné pour moi car j'ai un
./config
répertoire juste sous ma base de projet avec 2 fichiers:application.properties
application-dev.properties
Dans
application.properties
j'ai:spring.profiles.active = dev # set my default profile to 'dev'
Dans
application-dev.properties
j'ai:server_host = localhost server_port = 8080
C'est le cas lorsque j'exécute mon gros pot à partir de la CLI, les
*.properties
fichiers seront lus à partir du répertoire./config
et tout va bien.Eh bien, il s'avère que ces fichiers de propriétés remplacent complètement le
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
paramètre@SpringBootTest
de mes spécifications Spock. Peu importe ce que j'ai essayé, même avecwebEnvironment
jeu àRANDOM_PORT
Spring, démarrerait toujours le conteneur Tomcat intégré sur le port 8080 (ou quelle que soit la valeur que j'avais définie dans mes./config/*.properties
fichiers).La SEULE façon dont j'ai pu surmonter cela a été d'ajouter une explicite
properties = "server_port=0"
à l'@SpringBootTest
annotation dans mes spécifications d'intégration Spock:@SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "server_port=0")
Puis, et alors seulement, Spring a finalement commencé à faire tourner Tomcat sur un port aléatoire. À mon humble avis, il s'agit d'un bogue du cadre de test Spring, mais je suis sûr qu'ils auront leur propre opinion à ce sujet.
J'espère que cela a aidé quelqu'un.
la source
Vous pouvez obtenir le port utilisé par une instance Tomcat intégrée pendant les tests en injectant la valeur local.server.port en tant que telle:
// Inject which port we were assigned @Value("${local.server.port}") int port;
la source
local.server.port
est défini uniquement lors de l'exécution avec@WebIntegrationTests
À partir de Spring Boot 1.4.0, vous pouvez l'utiliser dans votre test:
import org.springframework.boot.context.embedded.LocalServerPort; @SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT) public class MyTest { @LocalServerPort int randomPort; // ... }
la source
Aucune de ces solutions n'a fonctionné pour moi. J'avais besoin de connaître le port du serveur lors de la construction d'un bean de configuration Swagger. L'utilisation de ServerProperties a fonctionné pour moi:
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 } }
Cet exemple utilise la configuration automatique de Spring Boot et JAX-RS (pas Spring MVC).
la source
Après Spring Boot 2, beaucoup de choses ont changé. Les réponses données ci-dessus fonctionnent avant Spring Boot 2. Maintenant, si vous exécutez votre application avec des arguments d'exécution pour le port du serveur, vous n'obtiendrez que la valeur statique avec
@Value("${server.port}")
, qui est mentionnée dans le fichier application.properties . Maintenant, pour obtenir le port réel sur lequel le serveur s'exécute, utilisez la méthode suivante:@Autowired private ServletWebServerApplicationContext server; @GetMapping("/server-port") public String serverPort() { return "" + server.getWebServer().getPort(); }
De plus, si vous utilisez vos applications en tant que clients Eureka / Discovery avec une charge équilibrée
RestTemplate
ouWebClient
, la méthode ci-dessus renverra le numéro de port exact.la source
Vous pouvez obtenir le port du serveur depuis le
@Autowired private HttpServletRequest request; @GetMapping(value = "/port") public Object getServerPort() { System.out.println("I am from " + request.getServerPort()); return "I am from " + request.getServerPort(); }
la source
Veuillez vous assurer que vous avez importé le bon package
import org.springframework.core.env.Environment;
puis utilisez l'objet Environnement
@Autowired private Environment env; // Environment Object containts the port number @GetMapping("/status") public String status() { return "it is runing on"+(env.getProperty("local.server.port")); }
la source
Je l'ai résolu avec une sorte de bean proxy. Le client est initialisé quand il est nécessaire, d'ici là, le port devrait être disponible:
@Component public class GraphQLClient { private ApolloClient apolloClient; private final Environment environment; public GraphQLClient(Environment environment) { this.environment = environment; } public ApolloClient getApolloClient() { if (apolloClient == null) { String port = environment.getProperty("local.server.port"); initApolloClient(port); } return apolloClient; } public synchronized void initApolloClient(String port) { this.apolloClient = ApolloClient.builder() .serverUrl("http://localhost:" + port + "/graphql") .build(); } public <D extends Operation.Data, T, V extends Operation.Variables> GraphQLCallback<T> graphql(Operation<D, T, V> operation) { GraphQLCallback<T> graphQLCallback = new GraphQLCallback<>(); if (operation instanceof Query) { Query<D, T, V> query = (Query<D, T, V>) operation; getApolloClient() .query(query) .enqueue(graphQLCallback); } else { Mutation<D, T, V> mutation = (Mutation<D, T, V>) operation; getApolloClient() .mutate(mutation) .enqueue(graphQLCallback); } return graphQLCallback; } }
la source