Skip to content

Instantly share code, notes, and snippets.

@holyjak
Created October 22, 2020 22:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save holyjak/ca14054414c80c64be1709fca216e1a4 to your computer and use it in GitHub Desktop.
Save holyjak/ca14054414c80c64be1709fca216e1a4 to your computer and use it in GitHub Desktop.
WIP - troubleshooting 404 in Spring MVC 4

Spring 4 - 404 troubleshooting

See https://www.baeldung.com/spring-handler-mappings - explains BeanNameUrlHandlerMapping, SimpleUrlHandlerMapping

Debug DispatcherServlet - DispatcherServlet.getHandler

Why is a mapping from URL -> controller missing? In org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#initHandlerMethods see the detected beanNames (all beans) and the isHandler check a few lines down. -> detectHandlerMethods -> this.mappingRegistry.register

=> info or debug or trace logs on org.springframework.web.servlet.handler.AbstractHandlerMethodMapping

Upon request:

  • org.springframework.web.servlet.DispatcherServlet#doService -> doDispatch calls getHandler, which looks into this.handlerMappings
  • org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerMethods -> .MappingRegistry#getMappings -> this.mappingLookup
  • org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal

beanName requestMappingHandlerMapping sees only 39 beanNames => 12 in mappingLookup, 25 in urlLookup

Docs: beans defined in the parent context are accessible in the child contexts - but the mapping does not search the parent context by default

Why isn't a css/js/.. resource found?

(Presumably added via WebMvcConfigurationSupport.addResourceHandlers(ResourceHandlerRegistry)) => Is the mapping as expected in the mappingRegistry? (see the previous section) If it is:

Debug lookup in the SimpleUrlHandlerMapping- debug org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#getHandlerInternal - see lookupPath, drill down to lookupHandler() - here it runs getPathMatcher().match(registeredPattern, urlPath)
-> org.springframework.web.servlet.resource.ResourceHttpRequestHandler#handleRequest -> getResource() which tries to find the resource on the classpath / ...
-> org.springframework.web.servlet.resource.PathResourceResolver#getResource(java.lang.String, java.util.List<? extends org.springframework.core.io.Resource>)

NOTE: Inside org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#lookupHandler look at the call to getPathMatcher().extractPathWithinPattern

lookupPath=/myapp/assets-verMS4wLjAtU05BUFNIT1Q=/myapp.css RESOURCE PATH=assets-verMS4wLjAtU05BUFNIT1Q=/myapp.css

AntPathMatcher.extractPathWithinPattern("/myapp/assets-ver{hash:.+?}/**/*", "/myapp/assets-verMS4wLjAtU05BUFNIT1Q=/myapp.css") => does stupid patternPart.indexOf('*') > -1 || patternPart.indexOf('?') check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment