4

(probably) solved `or at least it seems to be. I'm not really sure where it was the problem. For sure the config suggested by Biju Kunjummen, it's working and seems to me cleaner. What I'm doing now, to not generate mess is to work only inside Eclipse, sometimes cleaning the projects and never using maven to package & deploy it (at least during day to day programming, I guess with some robust maven script or CI Server everything will work fine too).

I'm trying to setup a Rest API with Spring MVC. I've read a lot of documentation but I'm still getting the error in the subject:

No mapping found for HTTP request with URI [/ecommerce-api/rest/checkout] in DispatcherServlet

The problem is exactly the same reported (and solved) in other similar questions, like this one FIXED: "No mapping found" Trying to set up a RESTfull interface using Spring-MVC

The really strange thing is that, without apparently changing anything in my code, sometime it works and sometimes it doesn't. I'm pretty sure nothing changes between the two moments, since for example sometime I'm physically away then I come back and it stops working.

At this particular moment, my code is the following:

web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/api-dispatcher-servlet.xml
    </param-value>
</context-param>


<servlet>
    <servlet-name>api-dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>api-dispatcher</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>


</web-app>

api-dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.myapp.api.ecommerce.controller" />
    <context:annotation-config />
    <mvc:annotation-driven />

</beans:beans>

com.myapp.ecommerce.controller.CheckoutController

package com.myapp.api.ecommerce.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.myapp.ecommerce.service.checkout.manager.CheckoutManager;
import com.myapp.ecommerce.service.checkout.manager.CheckoutManagerImpl;
import com.myapp.ecommerce.service.checkout.model.Checkout;


@Controller
@RequestMapping("/checkout")
public class CheckoutController {


    private CheckoutManager checkoutManager = new CheckoutManagerImpl();

    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody Checkout getCheckout() {

            return checkoutManager.findById("514f2a8e20f7a78a1400001f");
    }


}

A snippet of the log file of the application server (VFabric but I've also tried with Tomcat 7) when I try to GET ecommerce-api/rest/checkout:

2013-09-05 22:31:37,760 DEBUG [tomcat-http--5] servlet.DispatcherServlet (DispatcherServlet.java:823) - DispatcherServlet with name 'api-dispatcher' processing GET request for [/ecommerce-api/rest/checkout]
2013-09-05 22:31:37,763 DEBUG [tomcat-http--5] handler.AbstractHandlerMethodMapping (AbstractHandlerMethodMapping.java:220) - Looking up handler method for path /checkout
2013-09-05 22:31:37,763 DEBUG [tomcat-http--5] handler.AbstractHandlerMethodMapping (AbstractHandlerMethodMapping.java:230) - Did not find handler method for [/checkout]
2013-09-05 22:31:37,764 WARN  [tomcat-http--5] servlet.DispatcherServlet (DispatcherServlet.java:1108) - No mapping found for HTTP request with URI [/ecommerce-api/rest/checkout] in DispatcherServlet with name 'api-dispatcher'
2013-09-05 22:31:37,764 DEBUG [tomcat-http--5] servlet.FrameworkServlet (FrameworkServlet.java:966) - Successfully completed request

I really don't know what to do since it worked since last time I shut down my Mac and until that moment I thought to know how to do it.

Community
  • 1
  • 1
Alexio Cassani
  • 269
  • 2
  • 6
  • 19

4 Answers4

2

Weird behaviour is often caused by inconsistency in your compiled and source files. I suggest you to perform proper cleaning (assume you are using eclipse). Stop server, then perform Project -> clean. After that clean server. Try restart your application.

Other tip is try to debug what is happening when spring is looking for correct handler.

svobol13
  • 1,842
  • 3
  • 25
  • 40
  • Thank you, after cleaning the project I saw it working for sometime. Now suddenly it stopped again :-( What I do is: 1- stop the vFabric Server and clean its working dir 2- clean the project 3- mvn clean 4- mvn package 5- publish it again to the vFabric server. But the behavior is still negative: 80% times it doesn't work, 20% it does... – Alexio Cassani Sep 06 '13 at 10:15
  • Now after restarting Eclipse, cleaning the project again and having deployed again it works... – Alexio Cassani Sep 06 '13 at 10:29
2

I see one problem, you are loading up the same context file (api-dispatcher-servlet.xml) twice. Essentially a typical Spring based web application has two application contexts, the first is the ROOT application context loaded up through the ContextLoaderListener, the second is the Web application context loaded up through DispatcherServlet, in your case both these are pointing to the exact same configuration file which is api-dispatcher-servlet.xml. I would recommend you do this and see if it fixes the inconsistent behavior:

.1. Create say a applicationContext.xml file, for now it need not have any beans defined, later you can put your service related beans in this file.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">


</beans>

.2. Load this context through your ContextLoaderListener, in your web.xml:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/applicationContext.xml
    </param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

.3. Load up api-dispatcher-servlet.xml through your DispatcherServlet, you have the right entries for this already, but it may be better to make this explicit this way:

<servlet>
    <servlet-name>api-dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/api-dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>api-dispatcher</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
  • I've changed the xml files as you suggested (thanks, btw) but I still get the same behavior. In any case I'm keeping your configuration since it worked for a couple of times (after I've also cleaned the project as suggested by @svobol13). – Alexio Cassani Sep 06 '13 at 10:14
2

I am using @RestController instead of @Controller and I am getting the same error.

WARN org.springframework.web.servlet.PageNotFound noHandlerFound - No mapping found for HTTP request with URI [/something/JsonResponseBody] in DispatcherServlet with name 'dispatcher'

Almost everywhere I have searched its stated that we don't need to use @ResponseBody when we use @RestController, however, this is exactly what is making it work.

Following is working for me and it won't work if I remove @ResponseBody-

@RestController
public class MyController {
    @RequestMapping(path = "/dummy")
    @ResponseBody
    public DummyObject getDummy() {
        return new DummyObject("Some data");
    }
}

I am using Spring MVC 4.x, WebInitiliazer and 100% code-based approach.

YMMV

thisdotnull
  • 812
  • 1
  • 7
  • 20
0

It happened to me also, if your web-app was running fine and have changed nothing to it and it stopped working, then below steps are for you:

  1. If you are running a maven project, try to do maven clean and then maven install and then again try to run.

  2. Try to reconfigure your TomCat Configurations. You can follow http://www.vogella.com/tutorials/EclipseWTP/article.html.

Regards

Yash Bansal
  • 402
  • 5
  • 10