java - Why does Spring MVC respond with a 404 and report "No mapping found for HTTP request with URI [...] in DispatcherServlet"? -


i'm writing spring mvc application, deployed on tomcat. see following minimal, complete, , verifiable example:

public class application extends abstractannotationconfigdispatcherservletinitializer {     protected class<?>[] getrootconfigclasses() {         return new class<?>[] { };     }     protected class<?>[] getservletconfigclasses() {         return new class<?>[] { springservletconfig.class };     }     protected string[] getservletmappings() {         return new string[] { "/*" };     } } 

where springservletconfig

@configuration @componentscan("com.example.controllers") @enablewebmvc public class springservletconfig {     @bean     public internalresourceviewresolver resolver() {         internalresourceviewresolver vr = new internalresourceviewresolver();         vr.setprefix("/web-inf/jsps/");         vr.setsuffix(".jsp");         return vr;     } } 

finally, have @controller in package com.example.controllers

@controller public class examplecontroller {     @requestmapping(path = "/home", method = requestmethod.get)     public string example() {         return "index";     } } 

my application's context name example. when send request to

http://localhost:8080/example/home 

the application responds http status 404 , logs following

warn  o.s.web.servlet.pagenotfound - no mapping found http request uri `[/example/web-inf/jsps/index.jsp]` in `dispatcherservlet` name 'dispatcher' 

i have jsp resource @ /web-inf/jsps/index.jsp expected spring mvc use controller handle request , forward jsp, why responding 404?


this meant canonical post questions warning message.

your standard spring mvc application serve requests through dispatcherservlet you've registered servlet container.

the dispatcherservlet looks @ applicationcontext and, if available, applicationcontext registered contextloaderlistener special beans needs setup request serving logic. these beans described in documentation.

arguably important, beans of type handlermapping map

incoming requests handlers , list of pre- , post-processors (handler interceptors) based on criteria details of vary handlermapping implementation. popular implementation supports annotated controllers other implementations exists well.

the javadoc of handlermapping further describes how implementations must behave.

the dispatcherservlet finds beans of type , registers them in order (can customized). while serving request, dispatcherservlet loops through these handlermapping objects , tests each of them gethandler find 1 can handle incoming request, represented standard httpservletrequest. of 4.3.x, if doesn't find any, logs warning see

no mapping found http request uri [/some/path] in dispatcherservlet name somename

and either throws nohandlerfoundexception or commits response 404 not found status code.

why didn't dispatcherservlet find handlermapping handle request?

the common handlermapping implementation requestmappinghandlermapping, handles registering @controller beans handlers (really @requestmapping annotated methods). can either declare bean of type (with @bean or <bean> or other mechanism) or can use the built-in options. these are:

  1. annotate @configuration class @enablewebmvc.
  2. declare <mvc:annotation-driven /> member in xml configuration.

as link above describes, both of these register requestmappinghandlermapping bean (and bunch of other stuff). however, handlermapping isn't useful without handler. requestmappinghandlermapping expects @controller beans need declare too, through @bean methods in java configuration or <bean> declarations in xml configuration or through component scanning of @controller annotated classes in either. make sure these beans present.

if you're getting warning message , 404 , you've configured of above correctly, then you're sending request wrong uri, 1 isn't handled detected @requestmapping annotated handler method.

the spring-webmvc library offers other built-in handlermapping implementations. example, beannameurlhandlermapping maps

from urls beans names start slash ("/")

and can write own. obviously, you'll have make sure request you're sending matches @ least 1 of registered handlermapping object's handlers.

if don't explicitly register handlermapping beans (or if detectallhandlermappings true), dispatcherservlet registers defaults. these defined in dispatcherservlet.properties in same package dispatcherservlet class. beannameurlhandlermapping , defaultannotationhandlermapping (which similar requestmappinghandlermapping deprecated).

debugging

spring mvc log handlers registered through requestmappinghandlermapping. example, @controller like

@controller public class examplecontroller {     @requestmapping(path = "/example", method = requestmethod.get, headers = "x-custom")     public string example() {         return "example-view-name";     } } 

will log following @ info level

mapped "{[/example],methods=[get],headers=[x-custom]}" onto public java.lang.string com.spring.servlet.examplecontroller.example() 

this describes mapping registered. when see warning no handler found, compare uri in message mapping listed here. restrictions specified in @requestmapping must match spring mvc select handler.

other handlermapping implementations log own statements should hint mappings , corresponding handlers.

similarly, enable spring logging @ debug level see beans spring registers. should report annotated classes finds, packages scans, , beans initializes. if ones expected aren't present, review applicationcontext configuration.

other common mistakes

a dispatcherservlet typical java ee servlet. register typical <web.xml> <servlet-class> , <servlet-mapping> declaration, or directly through servletcontext#addservlet in webapplicationinitializer, or whatever mechanism spring boot uses. such, must rely on url mapping logic specified in servlet specification, see chapter 12. see also

with in mind, common mistake register dispatcherservlet url mapping of /*, returning view name @requestmapping handler method, , expecting jsp rendered. example, consider handler method like

@requestmapping(path = "/example", method = requestmethod.get) public string example() {     return "example-view-name"; } 

with internalresourceviewresolver

@bean public internalresourceviewresolver resolver() {     internalresourceviewresolver vr = new internalresourceviewresolver();     vr.setprefix("/web-inf/jsps/");     vr.setsuffix(".jsp");     return vr; } 

you might expect request forwarded jsp resource @ path /web-inf/jsps/example-view-name.jsp. won't happen. instead, assuming context name of example, disaptcherservlet report

no mapping found http request uri [/example/web-inf/jsps/example-view-name.jsp] in dispatcherservlet name 'dispatcher'

because dispatcherservlet mapped /* , /* matches (except exact matches, have higher priority), dispatcherservlet chosen handle forward jstlview (returned internalresourceviewresolver). in every case, dispatcherservlet not configured handle such request.

instead, in simplistic case, should register dispatcherservlet /, marking default servlet. default servlet last match request. allow typical servlet container chose internal servlet implementation, mapped *.jsp, handle jsp resource (for example, tomcat has jspservlet), before trying default servlet.

that's you're seeing in example.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -