Este aplicativo não possui mapeamento explícito para / erro


108

Usei o maven para fazer o tutorial https://spring.io/guides/gs/uploading-files/
Todos os códigos que usei foram copiados.

O aplicativo pode ser executado, mas recebo o erro:

Whitelabel Error Page Este aplicativo não possui mapeamento explícito para / error, então você está vendo isso como um fallback. Ter 30 de junho 17:24:02 CST 2015 Ocorreu um erro inesperado (tipo = Não encontrado, status = 404). Nenhuma mensagem disponível

Como posso corrigir isso?


adicionou seu comentário à postagem - você mesmo pode editá-lo. Isso é melhor do que comentar sua própria postagem
Alexander

Respostas:


137

Certifique-se de que sua classe principal esteja em um pacote raiz acima das outras classes.

Quando você executa um aplicativo Spring Boot, (ou seja, uma classe anotada com @SpringBootApplication), o Spring irá apenas verificar as classes abaixo do seu pacote de classe principal.

com
   +- APP
         +- Application.java  <--- your main class should be here, above your controller classes
         |
         +- model
         |   +- user.java
         +- controller
             +- UserController.java

4
Acima ou no mesmo nível?
Martin Erlic

21
Passei quase 2 horas da minha vida tentando descobrir isso!
Rakesh

7
Também tentei isso. Ainda erro. Pelo menos a página principal, ou seja, localhost: 8080, deve mostrar a página inicial do Tomcat, não é? Mas isso também não está aparecendo
zulkarnain shah

Obrigado pela dica. Eu costumava ser um usuário do Eclipse e essa configuração não era necessária, mas agora estou usando o IntelliJ e tive muita esperança.
Armer B.

@zulkarnainshah A página inicial usual do tomcat é gerada por um WAR que não está incluído aqui.
Thorbjørn Ravn Andersen

61

Quando criamos um aplicativo de inicialização do Spring, fazemos anotações nele @SpringBootApplication. Esta anotação 'envolve' muitas outras anotações necessárias para o aplicativo funcionar. Uma dessas anotações é @ComponentScananotação. Esta anotação diz ao Spring para procurar componentes Spring e configurar o aplicativo para rodar.

Sua classe de aplicativo precisa estar no topo da sua hierarquia de pacotes, para que o Spring possa escanear subpacotes e descobrir os outros componentes necessários.

package com.test.spring.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

O trecho de código abaixo funciona porque o pacote do controlador está sob o com.test.spring.bootpacote

package com.test.spring.boot.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

    @RequestMapping("/")
    public String home(){
        return "Hello World!";
    }
}

O snippet de código abaixo NÃO funciona porque o pacote do controlador NÃO está no com.test.spring.bootpacote

package com.test.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

     @RequestMapping("/")
     public String home(){
         return "Hello World!";
     }
 }

Da documentação do Spring Boot:

Muitos desenvolvedores do Spring Boot sempre têm sua classe principal anotada com @Configuration, @EnableAutoConfiguratione @ComponentScan. Uma vez que essas anotações são frequentemente usadas juntas (especialmente se você seguir as práticas recomendadas acima), Spring Boot oferece uma @SpringBootApplicationalternativa conveniente .

A @SpringBootApplicationanotação é equivalente a usar @Configuration, @EnableAutoConfiguratione @ComponentScancom os seus atributos padrão


3
Explicação muito boa. Obrigado
Lova Chittumuri

39

Você pode resolver isso adicionando um ErrorControllerem seu aplicativo. Você pode fazer com que o controlador de erro retorne a visualização necessária.

O controlador de erro em meu aplicativo é assim:

import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Basic Controller which is called for unhandled errors
 */
@Controller
public class AppErrorController implements ErrorController{

    /**
     * Error Attributes in the Application
     */
    private ErrorAttributes errorAttributes;

    private final static String ERROR_PATH = "/error";

    /**
     * Controller for the Error Controller
     * @param errorAttributes
     */
    public AppErrorController(ErrorAttributes errorAttributes) {
        this.errorAttributes = errorAttributes;
    }

    /**
     * Supports the HTML Error View
     * @param request
     * @return
     */
    @RequestMapping(value = ERROR_PATH, produces = "text/html")
    public ModelAndView errorHtml(HttpServletRequest request) {
        return new ModelAndView("/errors/error", getErrorAttributes(request, false));
    }

    /**
     * Supports other formats like JSON, XML
     * @param request
     * @return
     */
    @RequestMapping(value = ERROR_PATH)
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request, getTraceParameter(request));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<Map<String, Object>>(body, status);
    }

    /**
     * Returns the path of the error page.
     *
     * @return the error path
     */
    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }


    private boolean getTraceParameter(HttpServletRequest request) {
        String parameter = request.getParameter("trace");
        if (parameter == null) {
            return false;
        }
        return !"false".equals(parameter.toLowerCase());
    }

    private Map<String, Object> getErrorAttributes(HttpServletRequest request,
                                                   boolean includeStackTrace) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(request);
        return this.errorAttributes.getErrorAttributes(requestAttributes,
                includeStackTrace);
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request
                .getAttribute("javax.servlet.error.status_code");
        if (statusCode != null) {
            try {
                return HttpStatus.valueOf(statusCode);
            }
            catch (Exception ex) {
            }
        }
        return HttpStatus.INTERNAL_SERVER_ERROR;
    }
}

A classe acima é baseada na classe Springs BasicErrorController .

Você pode instanciar o acima ErrorControllerassim em um @Configurationarquivo:

 @Autowired
 private ErrorAttributes errorAttributes;

 @Bean
 public AppErrorController appErrorController(){return new AppErrorController(errorAttributes);}

Você pode escolher substituir o padrão ErrorAttributesimplementando ErrorAttributes . Mas na maioria dos casos, o DefaultErrorAttributes deve ser suficiente.


1
Seu link para a BasicErrorControlleraula 404s.
Stephane

@owaism: O link para BasicErrorControllernão é mais bom, você pode atualizar?
HDJEMAI

1
O link para BasicErrorControllerestá corrigido agora.
axiopisty de

15

No meu caso, a classe do controlador foi anotada com @Controller. Mudar isso para @RestControllerresolver o problema. Basicamente @RestControlleré @Controller + @ResponseBody So ou use @RestController, ou @Controllercom @ResponseBodyanotação com cada método.

Algumas notas úteis aqui: https://www.genuitec.com/spring-frameworkrestcontroller-vs-controller/


Funciona, mas de acordo com os exemplos, toda a configuração básica da Internet deve funcionar com @Controller. Alguém está ciente deste motivo pelo qual apenas RestController está funcionando?
supernova de

Ao anotar sua classe com @RestControllerela implicitamente adiciona a @ResponseBodyanotação, mas se você estiver usando a @Controlleranotação, você mesmo deve adicionar explicitamente esta anotação.
Robin Keskisarkka de

10

no meu caso, por causa da posição do pacote, o que significa que o pacote do controlador deve estar acima do pacote da classe principal

se meu pacote de classe principal é package co.companyname.spring.tutorial;qualquer pacote de controlador devepackage co.companyname.spring.tutorial.WHAT_EVER_HERE;

package co.companyname.spring.tutorial; // package for main class
@SpringBootApplication
public class FirstProjectApplication {

    public static void main(String[] args) {
        SpringApplication.run(FirstProjectApplication.class, args);
    }
}


package co.companyname.spring.tutorial.controllers; // package for controllers 

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController 
public class HelloController { 

@RequestMapping("/hello")  
public String hello() {   
 return "Hello, world"; 
 }}

depois de terminar a codificação, pressione o painel de inicialização

insira a descrição da imagem aqui

uma última coisa para se certificar de que o seu controlador está mapeando ou não apenas o console, você deve ver algo smilliar

Mapped "{[/hello]}" onto public java.lang.String co.companyname.spring.tutorial.controllers.HelloController.hello()

feliz codificação


9

Tente adicionar a dependência.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2
o que isso realmente faz?
Stealth Rabbi

Eu adicionei essa dependência e funcionou. Assim como @StealthRabbi ... Também estou me perguntando o que isso realmente faz.
twindham

@StealthRabbi Isso adiciona uma dependência a uma estrutura de modelos chamada Thymeleaf, que é uma alternativa e a abordagem preferencial para JSP. Esta resposta não é uma resposta real imo, jogar dependências não ajuda ninguém que esteja realmente interessado na questão central
Christian

9

Isso acontece quando uma página de erro explícita não é definida. Para definir uma página de erro, crie um mapeamento de / error com uma visão. por exemplo, o código abaixo mapeia para um valor de string sendo retornado em caso de erro.

package com.rumango.controller;

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class IndexController implements ErrorController{
    private final static String PATH = "/error";
    @Override
    @RequestMapping(PATH)
    @ResponseBody
    public String getErrorPath() {
        // TODO Auto-generated method stub
        return "No Mapping Found";
    }

}

Você pode adicionar alguma explicação ao seu código? Por que isso resolve a questão, quais são as partes cruciais?
Nico Haase

Há uma coisa específica a ser observada nesta resposta em relação ao Spring Boot que me causou um pouco de dor de cabeça no início. É importante implementar a interface ErrorController do springframework. Se você criar um endpoint do controlador mapeado para "/ error" sem fazer isso, receberá um erro informando que o método já está mapeado.
mmaynar1

5

Adicionei essa dependência e resolveu meu problema.

<dependency>
    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Aqui está minha teoria: se estivermos usando "@Controller", de alguma forma o Spring exigiria que tivéssemos um determinado mecanismo de template. E, neste caso, Thymeleaf. Portanto, é necessário o uso de folha timbrado com mola. Considerando que se estamos usando "@RestController", Spring Boot não requer um mecanismo de template. E, portanto, funciona sem Thymeleaf.
Yosi Pramajaya

4

Estou desenvolvendo o aplicativo Spring Boot por algumas semanas .. E eu estava pegando o mesmo erro abaixo;

Whitelabel Error Page Este aplicativo não possui mapeamento explícito para / error, então você está vendo isso como um fallback. Qui, 18 de janeiro, 14:12:11 AST 2018 Ocorreu um erro inesperado (tipo = Não encontrado, status = 404). Nenhuma mensagem disponível

Quando recebo essa mensagem de erro, percebi que meu controlador ou classe de controlador de repouso não está definido em meu projeto. Quero dizer, todos os nossos pacotes de controlador não são o mesmo pacote com a classe principal, que inclui a anotação @SpringBootApplication. Quero dizer, você precisa adicionar o nome do pacote do controlador à anotação @ComponentScan para sua classe principal que inclui a anotação @SpringBootApplication. Se você escrever códigos Abaixo, o seu problema estará resolvendo ... O mais importante é que você tem que adicionar o pacote de todos os controladores à anotação @ComponentScan como eu fiz na seção abaixo

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan({ "com.controller.package1, com.controller.package2, com.controller.package3, com.controller.packageN", "controller", "service" } // If our Controller class or Service class is not in the same packages we have //to add packages's name like this...directory(package) with main class
public class MainApp {
    public static void main(String[] args) {
        SpringApplication.run(MainApp.class, args);
    }
}

Espero que estes códigos ajudem alguém ...

Se você encontrar outra maneira de resolver este erro ou se tiver alguma sugestão para mim, por favor, escreva para comentários ... obrigado ...


4

Na classe principal, após a configuração "@SpringBootApplication", adicionar "@ComponentScan" sem nenhum argumento, funcionou para mim !!!

Classe Principal:

@SpringBootApplication
@ComponentScan
public class CommentStoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(CommentStoreApplication.class, args);

    }
}

Classe RestController:

@RestController
public class CommentStoreApp {

    @RequestMapping("/") 
    public String hello() {
        return "Hello World!";
    }
}

PS: Não deixe de executar os comandos mvn clean e mvn install antes de iniciar o aplicativo


4

Muito tarde para a festa. De acordo com a documentação oficial do Spring, "Spring Boot instala uma página de erro de whitelabel que você vê em um cliente de navegador se encontrar um erro de servidor." https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

  1. Você pode desativar o recurso configurando server.error.whitelabel.enabled=falseem application.yml ou application.properties arquivo.

2. A maneira recomendada é definir sua página de erro para que o usuário final possa entender. Na pasta resources / templates, crie um arquivo error.html e adicione dependência no arquivo pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

O Spring escolherá automaticamente a página error.html como o modelo de erro padrão. Nota: - Não se esqueça de atualizar o projeto maven após adicionar dependência.


3

Você pode estar recebendo o erro, ou seja,

"Este aplicativo não possui mapeamento explícito para / error, então você está vendo isso como um substituto."

Isso ocorre porque ele não está varrendo suas classes de controlador e serviço que você tem que especificar em sua classe principal () como este,

package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
**@ComponentScan({"com.example.demo", "controller", "service"})**
public class SpringBootMvcExample1Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootMvcExample1Application.class, args);
    }
}

Observação: aqui, especifiquei várias classes, como demo, controlador e serviço, a serem verificados, apenas para funcionar corretamente.


3

Você tem que organizar os pacotes de forma que o pacote contendo public static main (ou onde você escreveu @SpringBootApplication), seja o pai de todos os seus outros pacotes.


- com.mypachage + nameApplication.java - com.mypachage.model - com.mypachage.controller - com.mypachage.dao
sakgeek

3

Por padrão, o spring boot irá escanear o pacote atual para a definição de bean. Portanto, se o seu pacote atual onde a classe principal está definida e o pacote do controlador não é o mesmo ou o pacote do controlador não é um pacote filho do seu pacote de aplicativo principal, ele não fará a varredura do controlador. Para resolver este problema, pode-se incluir uma lista de pacotes para definição de bean no pacote principal

@SpringBootApplication(scanBasePackages = {"com.module.restapi1.controller"})

ou crie uma hierarquia de pacote onde o pacote filho é derivado do pacote principal

package com.module.restapi;
package com.module.restapi.controller

2

O problema é que você está navegando para localhost: 8080 / em vez de localhost: 8080 / upload conforme prescrito no guia. O Spring Boot tem uma página de erro padrão usada quando você navega para uma rota indefinida para evitar fornecer detalhes específicos do servidor (que podem ser vistos como um risco de segurança).

Suas opções são: visitar a página certa, adicionar sua própria página de destino ou substituir a página de erro em branco .

Para simplificar essa situação específica, atualizei o guia para que use / em vez de / upload.


2

Eu sei que não é exatamente uma resposta à pergunta, mas essa pergunta é a primeira que aparece no Google :)

Problema ("Este aplicativo não possui mapeamento explícito para / erro") aparece ao tentar acessar a IU do Swagger.

No meu caso, os problemas foram causados ​​por @RestController ("/ endpoint"), que não é tratado corretamente pelo swagger.

Então, isso resultou em erros:

@RestController("/endpoint")
public class EndpointController {

E isso foi bom

@RestController
@RequestMapping("/endpoint")
public class EndpointController {

2

isso pode acontecer se você esquecer a anotação @RestController no topo de sua classe de controlador import import org.springframework.web.bind.annotation.RestController;

e adicione a anotação como abaixo

consulte o exemplo simples abaixo

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;


@RestController
public class HelloController {
@RequestMapping("/")
    public String index() {
        return "Greetings from Spring Boot!";
    }

}

1

Mude @Controller para @RestController em sua classe de controlador e tudo deve correr bem.


1

Eu também obtive o mesmo erro e consegui resolver o erro adicionando a dependência abaixo ao meu pom.xml.

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

A razão é que estamos usando JSP como visão. O contêiner de servlet embutido padrão para Spring Boot Starter Web é tomcat. Para ativar o suporte para JSPs, precisaríamos adicionar uma dependência em tomcat-embed-jasper.

No meu caso, estava retornando um JSP como visualização do controlador. Espero que esta resposta ajude alguém que está lutando com o mesmo problema.


1

Eu estava enfrentando o mesmo problema, usando o gradle e foi resolvido ao adicionar as seguintes dependências-

compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
compile('org.apache.tomcat.embed:tomcat-embed-jasper')

antes eu estava perdendo o último causando o mesmo erro.


Eu tive o mesmo problema e estava faltando o plugin tomcat-embed-jasper em pom.xml. E tomcat-embed-jasper é importante para renderizar jsp.
rinilnath

boraji.com/… , isso levou a descobrir que tomcat-embed-jasper estava faltando
rinilnath

1

Eu estava enfrentando esse problema e mais tarde percebi que estava faltando a @Configurationanotação na MvcConfigaula que basicamente faz o mapeamento para ViewControllerse setViewNames.

Aqui está o conteúdo do arquivo:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
**@Configuration**
public class MvcConfig implements WebMvcConfigurer{
   public void addViewControllers(ViewControllerRegistry registry)
   {
      registry.addViewController("/").setViewName("login");
      registry.addViewController("/login").setViewName("login");
      registry.addViewController("/dashboard").setViewName("dashboard");
   }
}

Espero que isso ajude alguém !!


Isso fez isso por mim.
Anthony Okoth

1

Certifique-se de ter jasper e jstl na lista de dependências:

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>

Aqui está um projeto inicial em funcionamento - https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp

Autor: Biju Kunjummen


1

Preciso citar esse caminho e dar a referência aos pacotes e deu certo. Você pode excluir @EnableAutoConfigurationesta anotação, mas é necessário que eu ignore quaisquer dependências relacionadas ao banco de dados.

@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@ComponentScan(basePackages = {"your package 1", "your package2"})

public class CommentStoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(CommentStoreApplication.class, args);

    }
}

1

A classe principal precisa estar fora da estrutura de árvore dos pacotes de aplicativos. Por exemplo: exemplo


0

Tudo o que fiz para resolver esse tipo de problema foi mencionar a anotação @Configuration na classe MVCConfig.

Como este :

package com.example;

/**
 * Created by sartika.s.hasibuan on 1/10/2017.
 */
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@EnableAutoConfiguration
@Configuration
@ComponentScan
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/home").setViewName("home");
        registry.addViewController("/").setViewName("home");
        registry.addViewController("/hello").setViewName("hello");
        registry.addViewController("/login").setViewName("login");
    }

}

0

Eu tive um erro semelhante, eu uso a bota de mola e velocidade, minha solução é verificar o arquivo application.properties, spring.velocity.toolbox-config-location e descobri que esta propriedade está errada


0

No meu caso, esse problema ocorre ao executar o SpringApplication de dentro do IntelliJ depois de executá-lo primeiro com o maven.

Para resolver o problema, corro primeiro mvn clean. Em seguida, executo o SpringApplication de dentro do IntelliJ.


0

Certifique-se de seu principal. classe deve estar no topo de seus controladores. No caso do seguinte exemplo:

Main.class contendo:

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

EmployeeController. classe contendo:

@RestController
public class EmployeeController {
    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
        dataBinder.setDisallowedFields("id");
    }

    @RequestMapping(value = "/employee/save", method = RequestMethod.GET)
    public String save(){
        Employee newEmp = new Employee();
        newEmp.setAge(25);
        newEmp.setFirstName("Pikachu");
        newEmp.setId(100);
        return "Name: " + newEmp.getFirstName() + ", Age: " + newEmp.getAge() + ", Id = " + newEmp.getId();
    }
}

Se sua classe principal está na pasta raiz, assim como este caminho: {projectname} / src / main / java / main então certifique-se de seus controladores abaixo de sua classe principal. Por exemplo {projectname} / src / main / java / main / controllers .


0

Em seu arquivo java (digamos: Viper.java) tendo a classe principal, adicione: "@RestController" e @RequestMapping ("/")

@SpringBootApplication
@RestController
public class Viper {

  @RequestMapping("/")

   public String home(){
          return "This is what i was looking for";                      
     }

public static void main( String[] args){

   SpringApplication.run(Viper.class , args);
}

}

0

Verifique se você marcou a classe do controlador com a anotação @RestController .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.