Seu aplicativo Spring MVC padrão atenderá a todas as solicitações por meio de um DispatcherServlet
que você registrou com seu contêiner Servlet.
O DispatcherServlet
olha para ele ApplicationContext
e, se disponível, o ApplicationContext
registrado com um ContextLoaderListener
para beans especiais, ele precisa configurar sua lógica de atendimento de solicitação. Esses beans são descritos na documentação .
Provavelmente o mais importante, feijão do tipo HandlerMapping
mapa
solicitações de entrada para manipuladores e uma lista de pré e pós-processadores (interceptores de manipuladores) com base em alguns critérios cujos detalhes variam por HandlerMapping
implementação. A implementação mais popular suporta controladores anotados, mas também existem outras implementações.
O javadoc deHandlerMapping
descreve melhor como as implementações devem se comportar.
O DispatcherServlet
encontra todos os beans desse tipo e os registra em alguma ordem (pode ser personalizado). Enquanto atende a uma solicitação, o DispatcherServlet
loop atravessa esses HandlerMapping
objetos e testa cada um deles getHandler
para encontrar um que possa lidar com a solicitação recebida, representada como o padrão HttpServletRequest
. A partir de 4.3.x, se não encontrar nenhum , ele registra o aviso que você vê
Nenhum mapeamento encontrado para solicitação HTTP com URI [/some/path]
emDispatcherServlet
com o nome SomeName
e qualquer um um lança umNoHandlerFoundException
ou imediatamente compromete a resposta com um código de status 404 Not Found.
Por que não DispatcherServlet
encontrou umHandlerMapping
que pudesse atender ao meu pedido?
A HandlerMapping
implementação mais comum é RequestMappingHandlerMapping
, que lida com o registro de @Controller
beans como manipuladores (na verdade, seus @RequestMapping
métodos anotados). Você pode declarar um bean deste tipo sozinho (com @Bean
ou <bean>
ou outro mecanismo) ou pode usar as opções integradas . Esses são:
- Anote o seu
@Configuration
classe com @EnableWebMvc
.
- Declare um
<mvc:annotation-driven />
membro em sua configuração XML.
Como o link acima descreve, ambos registrarão um RequestMappingHandlerMapping
bean (e um monte de outras coisas). No entanto, um HandlerMapping
não é muito útil sem um manipulador. RequestMappingHandlerMapping
espera alguns @Controller
beans, então você precisa declará-los também, por meio de @Bean
métodos em uma configuração Java ou <bean>
declarações em uma configuração XML ou por meio de varredura de componente de@Controller
classes anotadas em qualquer um deles. Certifique-se de que esses grãos estejam presentes.
Se você está recebendo a mensagem de aviso e um 404 e configurou todos os itens acima corretamente, então você está enviando sua solicitação para o URI errado , um que não é tratado por um @RequestMapping
método de manipulador anotado detectado .
A spring-webmvc
biblioteca oferece outras HandlerMapping
implementações integradas . Por exemplo,BeanNameUrlHandlerMapping
mapas
de URLs a beans com nomes que começam com uma barra ("/")
e você sempre pode escrever o seu próprio. Obviamente, você terá que garantir que a solicitação que está enviando corresponda a pelo menos um dosHandlerMapping
manipuladores do objeto .
Se você não registrar implícita ou explicitamente nenhum HandlerMapping
bean (ou se detectAllHandlerMappings
estiver true
), o DispatcherServlet
registrará alguns padrões . Eles são definidos no DispatcherServlet.properties
mesmo pacote da DispatcherServlet
classe. Eles são BeanNameUrlHandlerMapping
e DefaultAnnotationHandlerMapping
(que é semelhante a, RequestMappingHandlerMapping
mas obsoleto).
Depurando
Spring MVC registrará os manipuladores registrados por meio de RequestMappingHandlerMapping
. Por exemplo, um @Controller
gosto
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
irá registrar o seguinte no nível de INFO
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
Isso descreve o mapeamento registrado. Ao ver o aviso de que nenhum manipulador foi encontrado, compare o URI na mensagem com o mapeamento listado aqui. Todas as restrições especificadas no@RequestMapping
devem corresponder para que o Spring MVC selecione o manipulador.
De outros HandlerMapping
implementações registram suas próprias instruções que devem sugerir seus mapeamentos e seus manipuladores correspondentes.
Da mesma forma, habilite o registro do Spring no nível DEBUG para ver quais beans o Spring registra. Ele deve relatar quais classes anotadas ele encontra, quais pacotes ele verifica e quais beans ele inicializa. Se os que você esperava não estiverem presentes, revise sua ApplicationContext
configuração.
Outros erros comuns
A DispatcherServlet
é apenas um Java EE típico Servlet
. Você o registra com sua declaração típica <web.xml>
<servlet-class>
e <servlet-mapping>
, ou diretamente por meio ServletContext#addServlet
de um WebApplicationInitializer
, ou com qualquer mecanismo que o Spring boot usa. Como tal, você deve confiar na lógica de mapeamento de url especificada na especificação do Servlet , consulte o Capítulo 12. Consulte também
Com isso em mente, um erro comum é registrar o DispatcherServlet
com um mapeamento de url de /*
, retornar um nome de visualização de um @RequestMapping
método manipulador e esperar que um JSP seja renderizado. Por exemplo, considere um método manipulador como
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
com um InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
você pode esperar que a solicitação seja encaminhada para um recurso JSP no caminho /WEB-INF/jsps/example-view-name.jsp
. Isso não vai acontecer. Em vez disso, assumindo um nome de contexto de Example
, oDisaptcherServlet
relatório
Nenhum mapeamento encontrados para solicitação HTTP com URI [/Example/WEB-INF/jsps/example-view-name.jsp]
no DispatcherServlet
com o nome 'expedidor'
Como o DispatcherServlet
é mapeado para /*
e /*
corresponde a tudo (exceto correspondências exatas, que têm maior prioridade), o DispatcherServlet
seria escolhido para lidar com o forward
do JstlView
(retornado pelo InternalResourceViewResolver
). Em quase todos os casos, o DispatcherServlet
não será configurado para lidar com essa solicitação .
Em vez disso, neste caso simplista, você deve registrar o DispatcherServlet
para /
, marcando-o como o servlet padrão. O servlet padrão é a última correspondência para uma solicitação. Isso permitirá que seu contêiner de servlet típico escolha uma implementação Servlet interna, mapeada para *.jsp
, para lidar com o recurso JSP (por exemplo, Tomcat temJspServlet
), antes de tentar com o servlet padrão.
Isso é o que você está vendo em seu exemplo.
@EnableWebMvc
em uma@Configuration
classe anotada não faz isso. Tudo o que ele faz é adicionar uma série de manipuladores / adaptadores Spring MVC padrão ao contexto do aplicativo. O registro de umDispatcherServlet
para servir/
é um processo completamente separado que é feito de várias maneiras que descrevo na seção Outros erros comuns . Eu respondo à pergunta feita dois parágrafos abaixo do que você citou.Resolvi meu problema além do descrito antes: `
added tomcat-embed-jasper:
`from: Arquivo JSP não renderizado no aplicativo da web Spring Boot
fonte
No meu caso, eu estava seguindo a documentação do Interceptors Spring para a versão 5.1.2 (enquanto usava Spring Boot v2.0.4.RELEASE ) e a
WebConfig
classe tinha a anotação@EnableWebMvc
, que parecia estar em conflito com outra coisa em meu aplicativo que estava impedindo minha estática ativos sejam resolvidos corretamente (ou seja, nenhum arquivo CSS ou JS estava sendo devolvido ao cliente).Depois de tentar várias coisas diferentes, tentei remover o
@EnableWebMvc
e funcionou!Editar: aqui está a documentação de referência que diz que você deve remover a
@EnableWebMvc
anotaçãoAparentemente, pelo menos no meu caso, já estou configurando meu aplicativo Spring (embora não usando
web.xml
ou qualquer outro arquivo estático, é definitivamente programaticamente), então era um conflito aí.fonte
Tente corrigir seu código com a seguinte alteração em seu arquivo de configuração. A configuração Java é usada em vez de
application.properties
. Não se esqueça de habilitar a configuração noconfigureDefaultServletHandling
método.Eu uso o Gradle, você deve ter as seguintes dependências em
pom.xml
:fonte
Encontrei outro motivo para o mesmo erro. Isso também pode ser devido aos arquivos de classe não gerados para seu arquivo controller.java. Como resultado, o servlet do dispatcher mencionado em web.xml não consegue mapeá-lo para o método apropriado na classe do controlador.
No eclipse, em Projeto-> selecione limpar -> Construir Projeto. Verifique se o arquivo de classe foi gerado para o arquivo do controlador em construções em sua área de trabalho.
fonte
Para mim, descobri que minhas classes de destino foram geradas em um padrão de pasta diferente da origem. Isso é possivelmente no eclipse, eu adiciono pastas para conter meus controladores e não os adiciono como pacotes. Então acabei definindo o caminho incorreto na configuração do Spring.
Minha classe de destino estava gerando classes em app e eu estava me referindo a com.happy.app
Eu adicionei pacotes (não pastas) para com.happy.app e movi os arquivos de pastas para pacotes no eclipse e isso resolveu o problema.
fonte
Limpe seu servidor. Talvez exclua o servidor e adicione o projeto novamente e execute.
Pare o servidor Tomcat
Clique com o botão direito no servidor e selecione "Limpar"
Clique com o botão direito do mouse novamente no servidor e selecione "Limpar diretório de trabalho do Tomcat"
fonte
No meu caso, eu estava brincando com a importação de arquivos de configuração java secundários para um arquivo de configuração java principal. Ao criar arquivos de configuração secundários, alterei o nome da classe de configuração principal, mas não consegui atualizar o nome em web.xml. Portanto, sempre que reiniciei meu servidor tomcat, não estava vendo os manipuladores de mapeamento observados no console do Eclipse IDE e, quando tentei navegar para minha página inicial, encontrei este erro:
A correção foi atualizar o arquivo web.xml para que o nome antigo "WebConfig" fosse "MainConfig", simplesmente renomeando-o para refletir o nome mais recente do arquivo de configuração java principal (onde "MainConfig" é arbitrário e as palavras " Web "e" Principal "usados aqui não são um requisito de sintaxe). MainConfig foi importante, porque foi o arquivo que fez a varredura de componente para "WebController", minha classe de controlador Spring mvc que lida com minhas solicitações da web.
web.xml tinha isto:
O arquivo web.xml agora tem:
Agora estou vendo o mapeamento na janela do console:
E minha página da web está carregando novamente.
fonte
Eu tive o mesmo problema que
**No mapping found for HTTP request with URI [/some/path] in DispatcherServlet with name SomeName**
Depois de analisar por 2 a 4 dias, descobri a causa raiz. Os arquivos de classe não foram gerados depois de executar o projeto. Cliquei na guia do projeto.
Arquivos de classe para código-fonte foram gerados. Isso resolveu meu problema. Para verificar se os arquivos de classe foram gerados ou não, verifique a pasta Build na pasta do seu projeto.
fonte