Aggiungi percorso contestuale all'applicazione Spring Boot


174

Sto cercando di impostare una root di contesto delle applicazioni Spring Boot a livello di codice. Il motivo della root di contesto è che vogliamo che si acceda all'app e che vengano aggiunti localhost:port/{app_name}tutti i percorsi del controller.

Ecco il file di configurazione dell'applicazione per l'app Web.

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

Ecco il controller di indice per la pagina principale.

@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";
  }

}

La nuova radice dell'applicazione dovrebbe essere in localhost:12378/mainstay, ma si trova ancora in localhost:12378.

Cosa mi manca per cui Spring Boot non accoda la root di contesto prima del mapping delle richieste?

Risposte:


382

Perché stai cercando di creare la tua soluzione. Spring-boot lo supporta già.

Se non ne hai già uno, aggiungi un application.propertiesfile a src\main\resources. Nel file delle proprietà, aggiungere 2 proprietà:

server.contextPath=/mainstay
server.port=12378

AGGIORNAMENTO (Spring Boot 2.0)

A partire da Spring Boot 2.0 (grazie al supporto di Spring MVC e Spring WebFlux) contextPathè stato modificato il seguente:

server.servlet.contextPath=/mainstay

È quindi possibile rimuovere la configurazione per il contenitore servlet personalizzato. Se è necessario eseguire una post elaborazione sul contenitore, è possibile aggiungere EmbeddedServletContainerCustomizerun'implementazione alla configurazione (ad esempio per aggiungere le pagine di errore).

Fondamentalmente le proprietà all'interno application.propertiesservono come default puoi sempre sovrascriverle usando un'altra application.propertiesaccanto all'artefatto che fornisci o aggiungendo parametri JVM ( -Dserver.port=6666).

Vedi anche la Guida di riferimento, in particolare la sezione delle proprietà .

La classe ServerPropertiesimplementa il EmbeddedServletContainerCustomizer. L'impostazione predefinita contextPathè "". Nel tuo esempio di codice stai impostando contextPathdirettamente su TomcatEmbeddedServletContainerFactory. Successivamente l' ServerPropertiesistanza elaborerà questa istanza e la ripristinerà dal tuo percorso a "". ( Questa riga fa un nullcontrollo ma, come impostazione predefinita "", fallisce sempre e imposta il contesto su ""e sovrascrivendo così il tuo).


Sebbene la risposta sia corretta (voglio dire, è possibile personalizzare le proprietà del contenitore servlet tramite il file delle proprietà dell'applicazione), perché esiste un metodo setContextPath (percorso), intendo, se il percorso non viene applicato, a cosa serve? A proposito, lo stesso vale per setContextPath (...) su EmbeddedServletContainerCustomizer
Modi

2
Mi aspetto EmbeddedServletContainerCustomizerche anche quello funzioni. Ma vorrei andare quello che viene fornito invece di provare a scappare da solo. Perché la tua soluzione non funziona ha a che fare con il comportamento predefinito programmato (accidentalmente?) In ServerProperties, il predefinito configurato contextPathè ""(e verifica nulle no "". Quest'ultimo sostituisce il tuo set esplicito contextPath.
M. Deinum,

Le proprietà sono cambiate, vedi la mia risposta di seguito.
Michael Simons,

5
Immagino che la proprietà in Spring Boot 2.0 sia "server.servlet.context-path"
IamVickyAV

34

Se si utilizza Spring Boot, non è necessario configurare le proprietà del server tramite l'inizializzazione di Vean.

Invece, se una funzionalità è disponibile per la configurazione di base, può essere impostata in un file "proprietà" chiamato application, che dovrebbe risiedere src\main\resourcesnella struttura dell'applicazione. Il file "proprietà" è disponibile in due formati

  1. .yml

  2. .properties

Il modo in cui specifichi o imposti le configurazioni differisce da un formato all'altro.

Nel vostro caso specifico, se si decide di utilizzare l'estensione .properties, allora si avrebbe un file chiamato application.propertiessotto src\main\resourcescon le seguenti impostazioni di configurazione

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

OTOH, se decidi di utilizzare l' .ymlestensione (es. application.yml), Dovrai impostare le configurazioni usando il seguente formato (es. YAML):

server:
    port: 8080
    contextPath: /context-path

Per le proprietà più comuni di Spring Boot fare riferimento al collegamento seguente:

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


22

Se si utilizza Spring Boot 2.0.0 utilizzare:

server.servlet.context-path

2
questo non funziona per i file di guerra distribuiti in Tomcat esterno
pise

1
Per me questo non ha funzionato (Spring Boot 2.1.2), ma ha funzionato in questo modo:server.servlet.contextPath=/api
lospejos,

2
@pise, sapevi come risolverlo per file di guerra in tomcat esterno?
Mohax,

11

si noti che le proprietà "server.context-path" o "server.servlet.context-path" [a partire da springboot 2.0.x] funzioneranno solo se si esegue la distribuzione su un contenitore incorporato, ad esempio Tomcat incorporato. Queste proprietà non avranno alcun effetto se, ad esempio, stai distribuendo la tua applicazione come guerra a un tomcat esterno.

vedi questa risposta qui: https://stackoverflow.com/a/43856300/4449859


Qualcuno ha capito come configurarlo durante la distribuzione su un tomcat esterno come warfile usando springboot v2.xe tomcat v8.5?
Soluzione semplice

@abdel anche io cerco la risposta, cosa succede se stiamo distribuendo il file di guerra in tomcat esterno come impostare il percorso di contesto.
pise

Lo stavo provando. È esattamente come quello che è stato dichiarato nel link sopra. Cambia il valore dell'attributo build -> finalName nel tuo percorso di contesto. Il file di guerra risultante utilizzerà quindi il percorso di contesto come nome file, che verrà quindi utilizzato da Tomcat come percorso di contesto.
DriLLFreAK100,

l'unico modo che mi viene in mente per la distribuzione come guerra in Tomcat esterno è quello di garantire che il nome della guerra corrisponda al contesto che stai cercando. quindi, ad esempio, se vuoi che il contesto sia '/ xyzwebapp', la tua guerra deve essere chiamata xyzwebapp.war. per raggiungere questo obiettivo, puoi aggiungere quanto segue all'elemento <build> nel tuo pom.xml: <finalName> xyzwebapp </finalName>.
abdel,

9

Le proprietà corrette sono

server.servlet.path

per configurare il percorso di DispatcherServlet

e

server.servlet.context-path

per configurare il percorso del contesto delle applicazioni al di sotto di quello.


Grazie mille
hema chandra,

2

Possiamo cambiare il percorso della root di contesto usando una semplice voce nel file delle proprietà.

application.properties

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

### Spring boot 2.x #########
server.servlet.context-path=/ClientApp

1

Possiamo impostarlo application.propertiescome API_CONTEXT_ROOT=/therootpath

E accediamo alla classe Java come menzionato di seguito

@Value("${API_CONTEXT_ROOT}")
private String contextRoot;

1

server.contextPath = / pilastro

funziona per me se avessi un file di guerra in JBOSS. Tra più file di guerra in cui ognuno contiene jboss-web.xml non ha funzionato. Ho dovuto inserire jboss-web.xml nella directory WEB-INF con il contenuto

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

1

In Spring Boot 1.5:

Aggiungi la seguente proprietà in application.properties:

server.context-path=/demo

Nota: /demoè l'URL del percorso di contesto.


1

Puoi farlo aggiungendo facilmente la porta e il percorso contestuale per aggiungere la configurazione nel file .properties [src \ main \ resources] e anche nel file .yml

configurazione del file application.porperties

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

configurazione del file application.yml

server:
port: 8084
contextPath: /context-path

Possiamo anche cambiarlo a livello di codice in avvio a molla.

@Component
public class ServerPortCustomizer implements     WebServerFactoryCustomizer<EmbeddedServletContainerCustomizer > {

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

}

Possiamo anche aggiungere un altro modo

@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);
    }       
}

usando il comando java spring boot 1.X

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

usando il comando java spring boot 2.X

java -jar my-app.jar --server.servlet.context-path=/spring-boot-app --server.port=8585 

possiamo anche aggiungere la porta del server a livello di codice
Ghulam Murtaza il


0

Possiamo impostarlo usando WebServerFactoryCustomizer. Questo può essere aggiunto direttamente nella classe del metodo principale di avvio di primavera che avvia Spring ApplicationContext.

@Bean
    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
      webServerFactoryCustomizer() {
        return factory -> factory.setContextPath("/demo");
}

0

Se si utilizza Spring Boot 2.x e si desidera passare la proprietà del percorso di contesto nella riga di comando, è necessario inserire il doppio // in questo modo:

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

Ha funzionato per me correre su Windows.


0
<!-- Server port-->

server.port=8080

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

server.servlet.context-path=/ems

La porta del server sarà 8080. Se si desidera qualsiasi altra porta, è possibile sostituire 8080. Percorso di contesto dell'applicazione Fro ho impostato ems. Puoi impostare un altro percorso in base alle tue esigenze
Bordoloi Parth,

1
Sono informazioni utili, perché non le aggiungi alla tua risposta anziché a un commento?
k-den,

0

Deve essere: server.servlet.context-path = / demo nota che non ha virgolette solo il valore preceduto da '/' questo valore va nel tuo file application.properties


-1

il percorso di contesto può essere integrato direttamente nel codice ma non è consigliabile poiché non può essere riutilizzato, quindi scrivere nel file application.properties server.contextPath = / nome della cartella in cui è stato inserito il codice contextPath = nome della cartella in cui è stato inserito il codice / Nota: guarda attentamente la barra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.