Spring Boot - jak uruchomić Port

Mam aplikację spring boot (używając embedded tomcat 7) i ustawiłem server.port = 0 w moim application.properties, więc mogę mieć losowy port. Po uruchomieniu serwera i uruchomieniu na porcie, muszę być w stanie uzyskać wybrany port.

Nie mogę użyć @Value("$server.port") ponieważ jest zero. Jest to pozornie prosta informacja, więc dlaczego nie mogę uzyskać do niej dostępu z mojego kodu java? Jak Mogę uzyskać do niego dostęp?

Author: Tucker, 2015-05-18

11 answers

Czy możliwy jest również dostęp do portu zarządzania w podobny sposób, np.:

  @SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT)
  public class MyTest {

    @LocalServerPort
    int randomServerPort;

    @LocalManagementPort
    int randomManagementPort;
 98
Author: LaughingLemon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-11 11:15:55

Środowisko wiosny przechowuje te informacje dla Ciebie.

@Autowired
Environment environment;

String port = environment.getProperty("local.server.port");

Na powierzchni wygląda to identycznie jak wstrzykiwanie pola z adnotacją @Value("${local.server.port}") (lub @LocalServerPort, które jest identyczne), podczas którego błąd automatycznego wiązania jest wyrzucany przy starcie, ponieważ wartość nie jest dostępna, dopóki kontekst nie zostanie w pełni zainicjowany. Różnica polega na tym, że to wywołanie jest domyślnie wykonywane w uruchomionej logice biznesowej, a nie wywoływane podczas uruchamiania aplikacji, a zatem' Lazy-fetch ' portu rozwiązuje problem ok.

 83
Author: hennr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-29 15:07:24

Podziękowania dla @ Dirk Lachowski za wskazanie mi w dobrym kierunku. Rozwiązanie nie jest tak eleganckie, jak bym chciał, ale działa. Czytając dokumenty spring, mogę słuchać na EmbeddedServletContainerInitializedevent i uzyskać port, gdy serwer jest uruchomiony. Oto jak to wygląda -

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();
      }
    }
 25
Author: Tucker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-18 21:20:44

Port, który jest używany przez osadzoną instancję Tomcat podczas testów, można uzyskać poprzez wstrzyknięcie lokalnego.serwer.wartość portu jako taka:

// Inject which port we were assigned
@Value("${local.server.port}")
int port;
 17
Author: bsyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 15:33:00

Po prostu, aby inni, którzy skonfigurowali swoje aplikacje, takie jak moje, skorzystali z tego, przez co przeszedłem...

Żadne z powyższych rozwiązań nie zadziałało na mnie, ponieważ mam katalog ./config tuż pod bazą projektu z 2 plikami:

application.properties
application-dev.properties

W application.properties mam:

spring.profiles.active = dev  # set my default profile to 'dev'

W application-dev.properties mam:

server_host = localhost
server_port = 8080

To jest tak, kiedy uruchamiam mój fat jar z CLI pliki {[8] } będą odczytywane z katalogu ./config i wszystko jest dobrze.

Cóż, okazuje się, że te pliki właściwości całkowicie nadpisują ustawienie {[10] } w @SpringBootTest W moich specyfikacjach Spocka. Bez względu na to, co próbowałem, nawet z webEnvironment ustawionym na RANDOM_PORT Spring zawsze uruchamiał osadzony kontener Tomcat na porcie 8080 (lub jakąkolwiek wartość ustawiłem w plikach ./config/*.properties).

Jedynym sposobem, w jaki udało mi się to przezwyciężyć, było dodanie wyraźnego properties = "server_port=0" do adnotacji @SpringBootTest W moich specyfikacjach integracji Spocka:

@SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "server_port=0")

Wtedy, i tylko wtedy Wiosna w końcu zaczęła kręcić Tomcat na przypadkowym porcie. IMHO to jest błąd Spring testing framework, ale jestem pewien, że będą mieli własne zdanie na ten temat.

Mam nadzieję, że to komuś pomogło.
 17
Author: Jacomoman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-03 00:36:50

Począwszy od Spring Boot 1.4.0 możesz użyć tego w swoim teście:

import org.springframework.boot.context.embedded.LocalServerPort;

@SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT)
public class MyTest {

  @LocalServerPort
  int randomPort;

  // ...
}
 12
Author: jabal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-05 21:17:48

Żadne z tych rozwiązań nie zadziałało. Podczas konstruowania konfiguracji Swaggera musiałem znać port serwera. Używanie ServerProperties zadziałało dla mnie:

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         
    }
}

Ten przykład wykorzystuje Spring Boot auto configuration i JAX-RS (nie Spring MVC).

 8
Author: mre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-07 03:05:50

Po Spring Boot 2 wiele się zmieniło. Powyższe odpowiedzi działają przed Spring Boot 2. Teraz, jeśli uruchomisz swoją aplikację z argumentami runtime dla portu serwera, wtedy otrzymasz tylko wartość statyczną z @Value("${server.port}"), o której mowa w aplikacji .właściwości pliku. Teraz, aby uzyskać rzeczywisty port, w którym działa serwer, użyj następującej metody:

    @Autowired
    private ServletWebServerApplicationContext server;

    @GetMapping("/server-port")
    public String serverPort() {

        return "" + server.getWebServer().getPort();
    }

Również, jeśli używasz aplikacji jako klientów Eureka / Discovery z obciążeniem zrównoważonym RestTemplate lub WebClient, powyższa metoda zwróci dokładny numer portu.

 2
Author: sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-19 12:42:36

Możesz pobrać port serwera z

HttpServletRequest
@Autowired
private HttpServletRequest request;

@GetMapping(value = "/port")
public Object getServerPort() {
   System.out.println("I am from " + request.getServerPort());
   return "I am from  " + request.getServerPort();
}
    
 1
Author: mafei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-15 17:39:44

Upewnij się, że zaimportowałeś poprawny pakiet

import org.springframework.core.env.Environment;

A następnie użyj obiektu Environment

@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"));
    }
 0
Author: Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-22 12:33:23

/ Align = "left" / Klient zostanie zainicjalizowany, gdy jest to potrzebne, wtedy port powinien być dostępny:

@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;
    }
}
 0
Author: Janning,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-25 18:37:11