How to debug 404 resource not found in spring mvc rest?

15,286

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 -

  1. You can do it by simply naming the war file as ROOT.war

  2. In ROOT.xml file, you have to specify this configuration <Context docBase="pathToWarFile" path="" reloadable="true" /> and make sure that your war file is not in webapps 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.

  1. 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.
  2. 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() + "'");
}
  1. Finally lookup for the class and add the logging-level.
Share:
15,286
diwakarb
Author by

diwakarb

Updated on July 20, 2022

Comments

  • diwakarb
    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
    diwakarb over 8 years
    Here's my ROOT.xml in Tomcat/conf/Catalina/localhost <Context docBase="platform" path="" reloadable="true" />
  • Omkar Puttagunta
    Omkar Puttagunta over 8 years
    are you deploying the app manually on Tomcat? If so which version?
  • Omkar Puttagunta
    Omkar Puttagunta over 8 years
    Ok. 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
    paulsm4 over 5 years
    Q: (Regarding Spring Boot): How exactly does one make sure Spring Boot is scanning the controller packages we think it should be scanning?
  • gary69
    gary69 over 5 years
    Spring 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
    paulsm4 over 5 years
    Q: 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
    gary69 over 5 years
    I think the only way would be to turn on debug logs and pipe them to a bash script stackoverflow.com/questions/8543421/…
  • paulsm4
    paulsm4 over 5 years
    Fair 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
    pdem almost 5 years
    It helps, but there are too much links in your answer, I feel like an archeologist!
  • Grim
    Grim almost 5 years
    @pdem developer avg salary is 47k, archaeologist is 58k. I support your salary increase if someone asks.
  • Ijaz
    Ijaz over 2 years
    helped big time.