How to debug 404 resource not found in spring mvc rest?
Solution 1
Place a breakpoint in
org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getMatchingPattern(String pattern, String lookupPath).
You will see why there is no match for your request.
Solution 2
You have to add the context path
in the url - localhost:8080/<context-path>/sample
.
Typically Context path
would be your war
file name if you deploy the app on Tomcat
. If your war
file name is helloworld.war
, then the URL would be localhost:8080/helloworld/sample
.
If you are using Tomcat
configured in Eclipse
, you can set the context-path
in the Modules tab.
Ways to Deploy your application to Tomcat
root -
You can do it by simply naming the
war
file asROOT.war
In
ROOT.xml
file, you have to specify this configuration<Context docBase="pathToWarFile" path="" reloadable="true" />
and make sure that yourwar
file is not inwebapps
folder.
If you deploy the application to the tomcat root, then there is no need to specify the context path
. You will get the homepage of your app with the url localhost:8080/
. In your case, you can call the controller method with the url localhost:8080/sample
.
Solution 3
Make sure you're scanning the packages your controllers are in. Otherwise spring won't create beans for your controllers and the paths they're listening for will return a 404.
Solution 4
If you have "SLF4J: Defaulting to no-operation (NOP) logger implementation" message:
Add a dependency to simple-logger like this:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
Otherwise
It needs reverse search.
- Find what message you like to see. This article gives me the hint that i need the message
No mapping found for HTTP request with
. - Search for sources in the web like this.
And here we have the line:
if (pageNotFoundLogger.isWarnEnabled()) {
pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + getRequestUri(request) +
"] in DispatcherServlet with name '" + getServletName() + "'");
}
- Finally lookup for the class and add the logging-level.
diwakarb
Updated on July 20, 2022Comments
-
diwakarb almost 2 years
I have a sample spring rest mvc application which has the following java code:
SampleController.java
import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("sample") public class SampleController { @RequestMapping(method = RequestMethod.GET, produces = "application/json") @ResponseBody public String getBatches()//@RequestParam(name = "name", required = true) String name) { return "Hello "; } }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ved</groupId> <artifactId>platform</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>platform Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring.version>4.2.1.RELEASE</spring.version> <jackson.version>2.6.2</jackson.version> <spring-boot.version>1.2.6.RELEASE</spring-boot.version> <filter.name>DEV</filter.name> <jersey.version>1.9</jersey.version> <base.directory>${basedir}</base.directory> </properties> <profiles> <profile> <id>local</id> <activation> <property> <name>env</name> <value>local</value> </property> </activation> <properties> <filter.name>DEV</filter.name> </properties> </profile> <profile> <id>qa</id> <activation> <property> <name>env</name> <value>qa</value> </property> </activation> <properties> <filter.name>QA</filter.name> </properties> </profile> <profile> <id>prod</id> <activation> <property> <name>env</name> <value>prod</value> </property> </activation> <properties> <filter.name>PROD</filter.name> </properties> </profile> </profiles> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>1.8.0.RELEASE</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.2.4</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>${jersey.version}</version> </dependency> </dependencies> <build> <!-- <filters> <filter>${basedir}/src/main/resources/ENV-${filter.name}/application.properties</filter> </filters> --> <finalName>platform</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> <debug>true</debug> <debuglevel>source,lines</debuglevel> <showDeprecation>true</showDeprecation> <archive> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <systemPropertyVariables> <environment>prod</environment> </systemPropertyVariables> </configuration> </plugin> <plugin> <groupId>com.google.code.maven-svn-revision-number-plugin</groupId> <artifactId>maven-svn-revision-number-plugin</artifactId> <version>1.7</version> <executions> <execution> <goals> <goal>revision</goal> </goals> </execution> </executions> <configuration> <entries> <entry> <prefix>svn</prefix> </entry> </entries> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> <version>1.0</version> <executions> <execution> <id>generate-timestamp</id> <phase>validate</phase> <goals> <goal>create-timestamp</goal> </goals> </execution> </executions> <configuration> <format>{0,date,yyyy-MM-dd HH:mm}</format> <items> <item>timestamp</item> </items> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> </project>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd"> <!-- <context:property-placeholder location="classpath:application.properties" /> --> <context:annotation-config /> <context:component-scan base-package="com.ved.platform" /> <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jacksonMessageConverter" /> </list> </property> </bean> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/views/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> </bean> </list> </property> </bean> --> <mvc:resources mapping="/resources/**" location="/resources/" /> <mvc:annotation-driven /> </beans>
homepage is giving me the apache page, but once I try to access 127.0.0.1:8080/sample It throws me a 404 error. Logs are all silent about it. Not sure how to fix this.
-
diwakarb over 8 yearsHere's my ROOT.xml in Tomcat/conf/Catalina/localhost <Context docBase="platform" path="" reloadable="true" />
-
Omkar Puttagunta over 8 yearsare you deploying the app manually on Tomcat? If so which version?
-
Omkar Puttagunta over 8 yearsOk. In your ROOT.xml, instead of docBase=platform, give the path to your war file and then restart the server..docBase='pathTowarFile' and restart the server
-
paulsm4 over 5 yearsQ: (Regarding Spring Boot): How exactly does one make sure Spring Boot is scanning the controller packages we think it should be scanning?
-
gary69 over 5 yearsSpring boot will automatically scan classes in the same package or in sub packages of your main class annotated with
@SpringBootApplication
. Otherwise you need to define an@ComponentScan
to give it extra packages to scan. -
paulsm4 over 5 yearsQ: So there's no way to get a list of classes that Spring Boot has actually scanned? Q: What about a complete list of URL path mappings?
-
gary69 over 5 yearsI think the only way would be to turn on debug logs and pipe them to a bash script stackoverflow.com/questions/8543421/…
-
paulsm4 over 5 yearsFair enough - thank you. The reason I asked is that I've turning on logging to TRACE - and there's still a lot of "magic" I'd like to understand better.
-
pdem almost 5 yearsIt helps, but there are too much links in your answer, I feel like an archeologist!
-
Grim almost 5 years@pdem developer avg salary is 47k, archaeologist is 58k. I support your salary increase if someone asks.
-
Ijaz over 2 yearshelped big time.