Announcement Announcement Module
Collapse
No announcement yet.
Dispatcher repeats the RequestMapping Path on REST update and delete Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dispatcher repeats the RequestMapping Path on REST update and delete

    Hello,

    I encountered a strange error, where dispatcher tries to resolve to an invalid handler URL.

    I run the following
    Code:
    curl -H "Content-type: application/json" -X PUT -d ' ...' http://localhost:8080/example/rest/customers/278170d1-8478-46a7-8967-52f0ca0feea0R
    I got 404 error and spring logs the message below. Note that it repeats the customers path twice
    Code:
    WARNING: No mapping found for HTTP request with URI [/example/rest/customers/customers/278170d1-8478-46a7-8967-52f0ca0feea0R] in DispatcherServlet with name 'rest'
    This is my REST code:
    Code:
    @Controller
    @RequestMapping("/customers")
    public class CustomerREST {
    
            ...
    	@RequestMapping(value = "/{id}", method = RequestMethod.GET, consumes = "application/json", produces = "application/json")
    	public @ResponseBody
    	Customer get(@PathVariable String id)  {
    	}
    
    	@RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    	public @ResponseBody
    	String create(@RequestBody Customer customer) {
    	}
    
    	@RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json")
    	public void update(@PathVariable String id, @RequestBody Customer customer) {
    	}
    
    	@RequestMapping(value = "/{id}", method = RequestMethod.DELETE, consumes = "application/json", produces = "application/json")
    	public void delete(@PathVariable String id) {
    	}
            ...
    }
    This is the content of rest-servlet.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
    
    	<mvc:annotation-driven />
    
    	<!-- Beware! Do not provide more than required scope here!! -->
    	<context:component-scan base-package="com.example.rest" />
    
    </beans>
    This is the content of web.xml
    Code:
            ...
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    	<listener>
    		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    	</listener>
            
            ...
            
            <servlet>
    		<servlet-name>rest</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath:rest-servlet.xml</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>rest</servlet-name>
    		<url-pattern>/rest/*</url-pattern>
    	</servlet-mapping>
    Spring logs the following info on the handler that it supports and it looks fine to me.
    Code:
    Jul 15, 2013 10:08:04 PM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
    INFO: Mapped "{[/customers/{id}],methods=[GET],params=[],headers=[],consumes=[application/json],produces=[application/json],custom=[]}" onto public com.example.model.Customer com.example.rest.CustomerREST.get(java.lang.String) 
    Jul 15, 2013 10:08:04 PM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
    INFO: Mapped "{[/customers/{id}],methods=[DELETE],params=[],headers=[],consumes=[application/json],produces=[application/json],custom=[]}" onto public void com.example.rest.CustomerREST.delete(java.lang.String) 
    Jul 15, 2013 10:08:04 PM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
    INFO: Mapped "{[/customers],methods=[POST],params=[],headers=[],consumes=[application/json],produces=[application/json],custom=[]}" onto public java.lang.String com.example.rest.CustomerREST.create(com.example.model.Customer) 
    Jul 15, 2013 10:08:04 PM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
    INFO: Mapped "{[/customers/{id}],methods=[PUT],params=[],headers=[],consumes=[application/json],produces=[application/json],custom=[]}" onto public void com.example.rest.CustomerREST.update(java.lang.String,com.example.model.Customer)
    The operation to create on "POST /customers" and get on "GET /customers/{id}" seems to work fine, however an update on "PUT /customers/{id}" and delete on "DELETE /customers/{id}" generates 404 and the dispatcher seems to repeat the request mapping path when it tries to resolve the handler. I am using spring version 3.1.6

    Has anyone encounter this issue? Any help would be appreciated.

    Regards,

    Ridwan
    Last edited by ridwant; Jul 16th, 2013, 01:01 AM.

  • #2
    I have the exact same problem. I tried stepping through the Spring code to find the problem, but so far not much luck.

    What I did see is that initially the right handler method is called, but somewhere along the way, the request altered or redirected with the wrong path. Not sure where this comes from yet. I'm going to keep looking, but any help is welcome.

    --JH

    Comment


    • #3
      Small update: the path gets mangled inside StringUtils.applyRelativePath, while the DispatcherServlet is looking for a view to render. This mangled url is then dispatched as a sub-request to render the view and there it fails... I wonder why our @ResponseBody annotations are not functioning properly....

      Comment


      • #4
        Got it! The problem was that I was missing the MappingJacksonHttpMessageConverter, causing the DispatcherServlet to be unable to send the Object back and trying to resolve a view. I added this piece of XML to my servlet-context.xml and now it's working like a charm again:

        Code:
            <beans:bean id="jacksonMessageConverter"
                        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
            <beans:bean
                    class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
                <beans:property name="messageConverters">
                    <beans:list>
                        <beans:ref bean="jacksonMessageConverter" />
                    </beans:list>
                </beans:property>
            </beans:bean>

        Comment

        Working...
        X