Dodaj ścieżkę kontekstową do aplikacji Spring Boot

174

Próbuję programowo ustawić kontekstowy katalog główny aplikacji Spring Boot. Powodem istnienia kontekstowego katalogu głównego jest to, że chcemy, aby aplikacja była dostępna localhost:port/{app_name}i wszystkie ścieżki kontrolera były do ​​niej dołączone.

Oto plik konfiguracyjny aplikacji internetowej.

@Configuration
public class ApplicationConfiguration {

  Logger logger = LoggerFactory.getLogger(ApplicationConfiguration.class);

  @Value("${mainstay.web.port:12378}")
  private String port;

  @Value("${mainstay.web.context:/mainstay}")
  private String context;

  private Set<ErrorPage> pageHandlers;

  @PostConstruct
  private void init(){
      pageHandlers = new HashSet<ErrorPage>();
      pageHandlers.add(new ErrorPage(HttpStatus.NOT_FOUND,"/notfound.html"));
      pageHandlers.add(new ErrorPage(HttpStatus.FORBIDDEN,"/forbidden.html"));
  }

  @Bean
  public EmbeddedServletContainerFactory servletContainer(){
      TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
      logger.info("Setting custom configuration for Mainstay:");
      logger.info("Setting port to {}",port);
      logger.info("Setting context to {}",context);
      factory.setPort(Integer.valueOf(port));
      factory.setContextPath(context);
      factory.setErrorPages(pageHandlers);
      return factory;
  }

  public String getPort() {
      return port;
  }

  public void setPort(String port) {
      this.port = port;
  }
}

Oto kontroler indeksu dla strony głównej.

@Controller
public class IndexController {

  Logger logger = LoggerFactory.getLogger(IndexController.class);

  @RequestMapping("/")
  public String index(Model model){
      logger.info("Setting index page title to Mainstay - Web");
      model.addAttribute("title","Mainstay - Web");
      return "index";
  }

}

Nowy katalog główny aplikacji powinien znajdować się pod adresem localhost:12378/mainstay, ale nadal znajduje się pod adresem localhost:12378.

Czego mi brakuje, co powoduje, że Spring Boot nie dołącza kontekstowego katalogu głównego przed mapowaniem żądania?

Correy S.
źródło

Odpowiedzi:

382

Dlaczego próbujesz stworzyć własne rozwiązanie. Spring-boot już to obsługuje.

Jeśli jeszcze go nie masz, dodaj application.propertiesplik do src\main\resources. W tym pliku właściwości dodaj 2 właściwości:

server.contextPath=/mainstay
server.port=12378

UPDATE (Spring Boot 2.0)

Począwszy od Spring Boot 2.0 (ze względu na obsługę zarówno Spring MVC, jak i Spring WebFlux) contextPath, zmieniono na następujące:

server.servlet.contextPath=/mainstay

Następnie można usunąć konfigurację niestandardowego kontenera serwletów. Jeśli chcesz wykonać dodatkowe przetwarzanie na kontenerze, możesz dodać plikEmbeddedServletContainerCustomizer implementację do swojej konfiguracji (na przykład, aby dodać strony błędów).

Zasadniczo właściwości wewnątrz application.propertiesusługi jako domyślne możesz zawsze nadpisać, używając innego application.propertiesobok dostarczanego artefaktu lub dodając parametry maszyny JVM (-Dserver.port=6666 ).

Zobacz także Poradnik, zwłaszcza sekcję dotyczącą właściwości .

Klasa ServerPropertiesimplementuje EmbeddedServletContainerCustomizer. Wartość domyślna contextPathto "". W przykładowym kodzie ustawiasz contextPathbezpośrednio na TomcatEmbeddedServletContainerFactory. Następnie ServerPropertiesinstancja przetworzy tę instancję i zresetuje ją ze ścieżki do "". ( Ta linia robi nullczek ale jako domyślny jest ""zawsze niepowodzeniem i ustawić kontekst ""i zastępując swoje).

M. Deinum
źródło
Chociaż twoja odpowiedź jest poprawna (mam na myśli, możesz dostosować właściwości kontenera serwletu za pomocą pliku właściwości aplikacji), dlaczego istnieje metoda setContextPath (ścieżka), to znaczy, jeśli ścieżka nie jest wymuszona, do czego to jest dobre? BTW, to samo dotyczy setContextPath (...) w EmbeddedServletContainerCustomizer
Modi,
2
Spodziewałbym się, że ten z EmbeddedServletContainerCustomizerteż zadziała. Ale poszedłbym, co jest przewidziane, zamiast próbować się spieszyć. Dlaczego twoje rozwiązanie nie działa, ma związek z domyślnym zachowaniem zaprogramowanym (przypadkowo?) W ServerProperties, domyślna konfiguracja contextPathto ""(i sprawdza, nullczy nie "". To drugie zastępuje twoje jawnie ustawione) contextPath.
M. Deinum,
Właściwości uległy zmianie, zobacz moją odpowiedź poniżej.
Michael Simons
5
Domyślam się, że właściwość w Spring Boot 2.0 to „server.servlet.context-path”
IamVickyAV,
34

Jeśli używasz Spring Boot, nie musisz konfigurować właściwości serwera poprzez inicjalizację Vean.

Zamiast tego, jeśli jedna funkcjonalność jest dostępna dla podstawowej konfiguracji, można ją ustawić w pliku „właściwości” o nazwie application, który powinien znajdować się src\main\resourcesw strukturze aplikacji. Plik „właściwości” jest dostępny w dwóch formatach

  1. .yml

  2. .properties

Sposób określania lub ustawiania konfiguracji różni się w zależności od formatu.

W twoim konkretnym przypadku, jeśli zdecydujesz się użyć rozszerzenia .properties, będziesz miał plik o nazwie application.propertiesunder src\main\resourcesz następującymi ustawieniami konfiguracji

server.port = 8080
server.contextPath = /context-path

OTOH, jeśli zdecydujesz się na użycie .ymlrozszerzenia (tj. application.yml), Musisz ustawić konfiguracje w następującym formacie (tj. YAML):

server:
    port: 8080
    contextPath: /context-path

Aby uzyskać więcej typowych właściwości Spring Boot, skorzystaj z poniższego łącza:

https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

Abhishek Shah
źródło
22

Jeśli używasz Spring Boot 2.0.0, użyj:

server.servlet.context-path
magemello
źródło
2
to nie działa w przypadku plików wojennych wdrożonych w zewnętrznym tomcat
pise
1
Dla mnie to nie zadziałało (Spring Boot 2.1.2), ale zadziałało tak:server.servlet.contextPath=/api
lospejos
2
@pise, czy wiesz, jak to naprawić dla pliku wojennego w zewnętrznym tomcat?
mohax
11

pamiętaj, że właściwości "server.context-path" lub "server.servlet.context-path" [począwszy od springboot 2.0.x] będą działać tylko wtedy, gdy wdrażasz do kontenera osadzonego, np. embedded tomcat. Te właściwości nie przyniosą efektu, jeśli na przykład wdrażasz aplikację jako wojnę na zewnętrznym urządzeniu Tomcat.

zobacz tę odpowiedź tutaj: https://stackoverflow.com/a/43856300/4449859

abdel
źródło
Czy ktoś wymyślił, jak to skonfigurować podczas wdrażania na zewnętrznym serwerze Tomcat jako warplik przy użyciu springboot v2.xi tomcat v8.5?
Proste rozwiązanie
@abdel nawet ja szukam odpowiedzi, a co jeśli wdrażamy plik wojenny w zewnętrznym tomcat, jak ustawić ścieżkę kontekstu.
pise
Wypróbowałem to. Dokładnie tak, jak podano w powyższym linku. Zmień wartość atrybutu build -> finalName na ścieżkę kontekstu. Wynikowy plik wojenny będzie wtedy używał ścieżki kontekstu jako nazwy pliku, która będzie następnie używana przez tomcat jako ścieżka kontekstu.
DriLLFreAK100
Jedynym sposobem, o którym mogę pomyśleć o rozmieszczeniu jako wojnie w zewnętrznym tomcat, jest upewnienie się, że nazwa wojny pasuje do kontekstu, którego szukasz. więc na przykład, jeśli chcesz, aby kontekst to „/ xyzwebapp”, twoja wojna musi mieć nazwę xyzwebapp.war. Aby to osiągnąć, możesz dodać następujące elementy do elementu <build> w swoim pom.xml: <finalName> xyzwebapp </finalName>.
abdel
9

Prawidłowe właściwości to

server.servlet.path

aby skonfigurować ścieżkę do DispatcherServlet

i

server.servlet.context-path

aby skonfigurować ścieżkę kontekstu aplikacji poniżej.

Michael Simons
źródło
Dziękuję bardzo
hema chandra
2

Możemy zmienić kontekstową ścieżkę główną za pomocą prostego wpisu w pliku właściwości.

application.properties

### Spring boot 1.x #########
server.contextPath=/ClientApp

### Spring boot 2.x #########
server.servlet.context-path=/ClientApp
ramakotireddy nagireddy
źródło
1

Możemy to ustawić w application.propertiesas API_CONTEXT_ROOT=/therootpath

Dostęp do niego uzyskujemy w klasie Java, jak wspomniano poniżej

@Value("${API_CONTEXT_ROOT}")
private String contextRoot;
Sanket
źródło
1

server.contextPath = / mainstay

działa dla mnie, gdybym miał jeden plik wojenny w JBOSS. Wśród wielu plików wojennych, z których każdy zawierał jboss-web.xml, nie działał. Musiałem umieścić jboss-web.xml w katalogu WEB-INF z zawartością

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
    <context-root>mainstay</context-root>
</jboss-web>
Gondri
źródło
1

In Spring Boot 1.5:

Dodaj następującą właściwość w application.properties:

server.context-path=/demo

Uwaga: /demoto adres URL ścieżki kontekstowej.

Piyush Anjikar
źródło
1

Możesz to zrobić, dodając port i ścieżkę kontekstu, aby dodać konfigurację w pliku [src \ main \ resources] .properties, a także w pliku .yml

Konfiguracja pliku application.porperties

server.port = 8084
server.contextPath = /context-path

Konfiguracja pliku application.yml

server:
port: 8084
contextPath: /context-path

Możemy to również zmienić programowo podczas rozruchu wiosennego.

@Component
public class ServerPortCustomizer implements     WebServerFactoryCustomizer<EmbeddedServletContainerCustomizer > {

@Override
public void customize(EmbeddedServletContainerCustomizer factory) {
    factory.setContextPath("/context-path");
    factory.setPort(8084);
}

}

Możemy też dodać inny sposób

@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {SpringApplication application =     new pringApplication(MyApplication.class);
    Map<String, Object> map = new HashMap<>();
    map.put("server.servlet.context-path", "/context-path");
    map.put("server.port", "808");
    application.setDefaultProperties(map);
    application.run(args);
    }       
}

używając java command spring boot 1.X

java -jar my-app.jar --server.contextPath=/spring-boot-app     --server.port=8585 

używając java command spring boot 2.X

java -jar my-app.jar --server.servlet.context-path=/spring-boot-app --server.port=8585 
Ghulam Murtaza
źródło
możemy również programowo dodać port serwera
Ghulam Murtaza
0

Jeśli używasz application.yml i wersji Spring powyżej 2.0, skonfiguruj w poniższy sposób.

server:
  port: 8081
  servlet:
     context-path: /demo-api

Teraz całe wywołanie api będzie wyglądać następująco : http: // localhost: 8081 / demo-api /

Swapnil Gangrade
źródło
0

Możemy to ustawić za pomocą WebServerFactoryCustomizer. Można to dodać bezpośrednio w głównej klasie metody rozruchu sprężyny, która uruchamia Spring ApplicationContext.

@Bean
    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
      webServerFactoryCustomizer() {
        return factory -> factory.setContextPath("/demo");
}
Pavan
źródło
0

Jeśli używasz Spring Boot 2.x i chcesz przekazać właściwość ścieżki kontekstu w wierszu poleceń, powinieneś umieścić podwójne // w ten sposób:

--server.servlet.context-path=//your-path

To zadziałało w przypadku mnie w oknach.

Marco
źródło
0
<!-- Server port-->

server.port=8080

<!--Context Path of the Application-->

server.servlet.context-path=/ems
Bordoloi Parth
źródło
Port serwera to 8080. Jeśli chcesz inny port, możesz zastąpić 8080. W ścieżce kontekstu aplikacji mam ustawione ems. Możesz ustawić inną ścieżkę zgodnie z wymaganiami
Bordoloi Parth
1
To przydatne informacje, dlaczego nie dodasz ich do odpowiedzi zamiast komentarza?
k-den
0

Musi to być: server.servlet.context-path = / demo uwaga, że ​​nie ma cudzysłowów, tylko wartość poprzedzona znakiem „/” ta wartość jest umieszczana w pliku application.properties

osiris a. suarez
źródło
-1

ścieżka kontekstu może być bezpośrednio zintegrowana z kodem, ale nie jest to zalecane, ponieważ nie można jej ponownie użyć, więc napisz w pliku application.properties server.contextPath = / nazwa folderu, w którym umieściłeś kod contextPath = nazwa folderu, w którym umieściłeś kod / Uwaga: uważnie obserwuj ukośnik.

saravanan
źródło