Spring MVC HTTP Status 405 - Request method 'POST' not supported - Backbone Request

46,452

You have already mapped /api/messages to the getMessagesInJSON method which only allows a GET request. Your POST request is mapping to a different path.

I suggest to omit the value attribute on your request mapping for createMessage.

@RequestMapping(method = RequestMethod.POST )
Share:
46,452
jantunes
Author by

jantunes

Updated on November 26, 2020

Comments

  • jantunes
    jantunes over 3 years

    I am new at Spring MVC and I am trying to build a Web Application from scratch using Spring MVC + Hibernate to serve something like a JSON Rest API, having this API consumed through Backbone at the client side. To do that I have started following this tutorial ( http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/ ) .

    So I have a model Message which will have the following REST API Interface:
    GET /api/messages               ( working ok )
    GET /api/messages/:id           ( working ok )
    DELETE /api/messages/:id        ( working ok )
    PUT /api/messages/:id           ( working ok )
    POST /api/messages              ( error: (DefaultHandlerExceptionResolver.java:194) - Request method 'POST' not supported)
    

    I expected this problem happens for PUT or DELETE requests when doing the request through a form, but not for a POST request. I am not even doing the request through a form. On the client side the request is done through Backbone like this:

    new App.Models.Message({ attributeA : 'a', attributeB : 'b' }).save();
    

    I have already tried to add the httpMethodFilter at web.xml as suggested in other Stackoverflow questions:

     <filter>
        <filter-name>httpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
     </filter>
    
     <filter-mapping>
        <filter-name>httpMethodFilter</filter-name>
        <servlet-name>mvc-dispatcher</servlet-name>
     </filter-mapping>  
    

    Has anyone had the same problem?

    I leave here my MessagesController:

    @Controller
    @RequestMapping("/api/messages")
    public class MessagesController {
    
        @Autowired  
        private MessageService messageService;
    
        @RequestMapping(method = RequestMethod.GET)
        public @ResponseBody List<Message> getMessagesInJSON(@RequestParam( value = "type", required = false ) String type) {   
            List<Message> messages = messageService.findAll();          
            return messages; 
        }
    
        @RequestMapping( value = "/{id}", method = RequestMethod.GET )
        public @ResponseBody Message getMessageInJson(@PathVariable Integer id ) {      
            Message message = messageService.findById(id);
            return message;     
        }
    
        @RequestMapping( value = "/{id}", method = RequestMethod.DELETE )
        @ResponseStatus( value = HttpStatus.NO_CONTENT )
        public void deleteMessage(@PathVariable Integer id ) throws NotFoundException {     
            messageService.delete(id);      
        }
    
        @RequestMapping( value = "/{id}", method = RequestMethod.PUT )
        @ResponseStatus( value = HttpStatus.NO_CONTENT )
        public void editMessage( @PathVariable Integer id, @RequestBody Message message ) throws NotFoundException {
            message.setId(id);
            messageService.update(message);
        }
    
        @RequestMapping( value = "/", method = RequestMethod.POST )
        @ResponseStatus(HttpStatus.CREATED)
        public @ResponseBody Message createMessage( @RequestBody Message message ) {        
            return messageService.create(message);
        }
    
    }
    

    Thanks a lot!

  • jantunes
    jantunes over 10 years
    Yes! That was the problem. Do you know why this happens? Thanks ;)
  • Bart
    Bart over 10 years
    I haven't looked at the code but I suspect it has to do with which request mapping value matches the actual request path. To avoid this in the future it's better you never actually map to "/" but leave it empty.