Adicionar caminho de contexto ao aplicativo Spring Boot

174

Estou tentando definir uma raiz de contexto de aplicativos Spring Boot programaticamente. O motivo da raiz de contexto é que queremos que o aplicativo seja acessado localhost:port/{app_name}e tenha todos os caminhos do controlador anexados a ele.

Aqui está o arquivo de configuração do aplicativo para o aplicativo da 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;
  }
}

Aqui está o controlador de índice da página principal.

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

}

A nova raiz do aplicativo deve estar em localhost:12378/mainstay, mas ainda está localizada em localhost:12378.

O que sinto falta está fazendo com que o Spring Boot não anexe a raiz de contexto antes do mapeamento da solicitação?

CorreyS
fonte

Respostas:

381

Por que você está tentando lançar sua própria solução. Spring-boot já suporta isso.

Se você ainda não possui um, adicione um application.propertiesarquivo a src\main\resources. Nesse arquivo de propriedades, adicione 2 propriedades:

server.contextPath=/mainstay
server.port=12378

ATUALIZAÇÃO (Spring Boot 2.0)

A partir do Spring Boot 2.0 (devido ao suporte do Spring MVC e do Spring WebFlux), contextPathele foi alterado para o seguinte:

server.servlet.contextPath=/mainstay

Você pode remover sua configuração para o contêiner de servlet customizado. Se você precisar fazer algum pós-processamento no contêiner, poderá adicionar uma EmbeddedServletContainerCustomizerimplementação à sua configuração (por exemplo, para adicionar as páginas de erro).

Basicamente, as propriedades dentro do application.propertiesservidor servem como padrão. Você sempre pode substituí-las usando outra application.propertiesao lado do artefato que você entrega ou adicionando parâmetros da JVM ( -Dserver.port=6666).

Consulte também o Guia de Referência, especialmente a seção de propriedades .

A classe ServerPropertiesimplementa o EmbeddedServletContainerCustomizer. O padrão para contextPathé "". No seu exemplo de código, você está configurando o contextPathdiretamente no TomcatEmbeddedServletContainerFactory. Em seguida, a ServerPropertiesinstância processará essa instância e a redefinirá do seu caminho para "". ( Essa linha faz uma nullverificação, mas, como padrão, ""ela sempre falha e define o contexto ""e, portanto, substitui o seu).

M. Deinum
fonte
Embora sua resposta esteja correta (quero dizer, você pode personalizar as propriedades do contêiner do servlet pelo arquivo de propriedades do aplicativo), por que existe um método setContextPath (path)? Quero dizer, se o caminho não é imposto, para que serve? BTW, o mesmo vale para o setContextPath (...) no EmbeddedServletContainerCustomizer
Modi
2
Eu esperaria que esse EmbeddedServletContainerCustomizertambém funcionasse. Mas eu iria o que é fornecido, em vez de tentar fugir sozinho. Por sua solução não trabalho tem a ver com o comportamento padrão programada (? Acidentalmente) no ServerProperties, o padrão configurado contextPathé ""(e ele verifica nulle não ""As últimas substituições seu explicitamente definido. contextPath.
M. Deinum
As propriedades foram alteradas, veja minha resposta abaixo.
22717 Michael Simons
5
Eu acho que a propriedade no Spring Boot 2.0 é "server.servlet.context-path"
IamVickyAV
34

Se você estiver usando o Spring Boot, não precisará configurar as propriedades do servidor via inicialização do Vean.

Em vez disso, se uma funcionalidade estiver disponível para configuração básica, ela poderá ser definida em um arquivo de "propriedades" chamado application, que deverá residir src\main\resourcesem sua estrutura de aplicativos. O arquivo "properties" está disponível em dois formatos

  1. .yml

  2. .properties

A maneira como você especifica ou define as configurações difere de um formato para outro.

No seu caso específico, se você decidir usar a extensão .properties, terá um arquivo chamado application.propertiessob src\main\resourcescom as seguintes definições de configuração

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

OTOH, se você decidir usar a .ymlextensão (ou seja application.yml), precisará definir as configurações usando o seguinte formato (ou seja YAML):

server:
    port: 8080
    contextPath: /context-path

Para propriedades mais comuns do Spring Boot, consulte o link abaixo:

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

Abhishek Shah
fonte
22

Se você usa o Spring Boot 2.0.0, use:

server.servlet.context-path
magemello
fonte
2
isso não funciona para a guerra arquivos implantado em tomcat externa
pise
1
Para mim, isso não funcionou (Spring Boot 2.1.2), mas funcionou:server.servlet.contextPath=/api
lospejos
2
@ pise, você sabia como corrigi-lo para o arquivo war no tomcat externo?
mohax 14/09/19
11

observe que as propriedades "server.context-path" ou "server.servlet.context-path" [a partir do springboot 2.0.x] somente funcionarão se você estiver implantando em um contêiner incorporado, por exemplo, tomcat incorporado. Essas propriedades não terão efeito se você estiver implementando seu aplicativo como uma guerra em um tomcat externo, por exemplo.

veja esta resposta aqui: https://stackoverflow.com/a/43856300/4449859

abdel
fonte
Alguém descobriu como configurar isso ao implantar em um tomcat externo como wararquivo usando springboot v2.xe tomcat v8.5?
Simple-Solution
@abdel, mesmo procurando a resposta, e se estivermos implantando o arquivo war no tomcat externo, como definir o caminho do contexto.
pise
Eu estava tentando. É exatamente como o que foi afirmado no link acima. Altere o valor do atributo build -> finalName para o caminho do seu contexto. O arquivo war resultante usará o caminho de contexto como o nome do arquivo, que será usado pelo tomcat para servir como o caminho de contexto.
DriLLFreAK100 22/02/19
a única maneira de pensar em implantar como guerra no tomcat externo é garantir que o nome da guerra corresponda ao contexto que você procura. portanto, por exemplo, se você quiser que o contexto seja '/ xyzwebapp', sua guerra deverá ser denominada xyzwebapp.war. para conseguir isso, você pode adicionar o seguinte ao elemento <build> no seu pom.xml: <finalName> xyzwebapp </finalName>.
Abdel
9

As propriedades corretas são

server.servlet.path

configurar o caminho do DispatcherServlet

e

server.servlet.context-path

para configurar o caminho do contexto de aplicativos abaixo disso.

Michael Simons
fonte
Muito obrigado
hema chandra
2

Podemos alterar o caminho da raiz de contexto usando uma entrada simples no arquivo de propriedades.

application.properties

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

### Spring boot 2.x #########
server.servlet.context-path=/ClientApp
ramakotireddy nagireddy
fonte
1

Podemos configurá-lo application.propertiescomo API_CONTEXT_ROOT=/therootpath

E acessamos na classe Java, conforme mencionado abaixo

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

server.contextPath = / mainstay

funciona para mim se eu tivesse um arquivo de guerra no JBOSS. Entre vários arquivos war em que cada um contém jboss-web.xml, não funcionou. Eu tive que colocar o jboss-web.xml dentro do diretório WEB-INF com conteúdo

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

No Spring Boot 1.5:

Adicione a seguinte propriedade em application.properties:

server.context-path=/demo

Nota: /demoé o URL do seu caminho de contexto.

Piyush Anjikar
fonte
1

Você pode fazer isso adicionando a porta e o caminho de contexto facilmente para adicionar a configuração no arquivo [src \ main \ resources] .properties e também no arquivo .yml

configuração do arquivo application.porperties

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

configuração do arquivo application.yml

server:
port: 8084
contextPath: /context-path

Também podemos alterá-lo programaticamente na inicialização da primavera.

@Component
public class ServerPortCustomizer implements     WebServerFactoryCustomizer<EmbeddedServletContainerCustomizer > {

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

}

Também podemos adicionar uma outra maneira

@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 o comando java spring boot 1.X

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

usando o comando java spring boot 2.X

java -jar my-app.jar --server.servlet.context-path=/spring-boot-app --server.port=8585 
Ghulam Murtaza
fonte
podemos também adicionar a porta do servidor através de programação
Ghulam Murtaza
0

Se você estiver usando a versão application.yml e spring acima de 2.0, configure-a da maneira abaixo.

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

Agora toda a chamada da API será como http: // localhost: 8081 / demo-api /

Swapnil Gangrade
fonte
0

Podemos configurá-lo usando WebServerFactoryCustomizer. Isso pode ser adicionado diretamente na classe de método principal de inicialização por primavera, que inicia o Spring ApplicationContext.

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

Se você usa o Spring Boot 2.xe deseja passar a propriedade do caminho de contexto na linha de comando, deve colocar double // assim:

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

Isso funcionou para mim correndo no Windows.

Marco
fonte
0
<!-- Server port-->

server.port=8080

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

server.servlet.context-path=/ems
Bordoloi Parth
fonte
A porta do servidor será 8080. se você quiser qualquer outra porta, poderá substituir o 8080. Para o caminho de contexto do aplicativo, configurei o ems. Você pode definir outro caminho conforme sua exigência
Bordoloi Parth
1
Essa é uma informação útil, por que você não a adiciona em sua resposta em vez de em um comentário?
k-den
0

Ele deve ser: server.servlet.context-path = / demo note que ele não possui aspas, apenas o valor precedido por '/' esse valor é inserido no arquivo application.properties

osiris a. suarez
fonte
-1

O caminho de contexto pode ser integrado diretamente ao código, mas não é aconselhável, pois não pode ser reutilizado, portanto, escreva no arquivo application.properties server.contextPath = / nome da pasta em que você colocou o código contextPath = nome da pasta em que você colocou o código / Nota: observe a barra com cuidado.

saravanan
fonte