Oct 14
A Simple REST controller for Spring MVC
Posted By: Praveen Ray
RESTful programming is all the rage these days – at least in Rails world. It's a simple way to perform request dispatching which is easy to understand and maps database CRUD operations into web requests elegantly. While Rails comes with REST routing built in, there is no such support in Spring MVC. However, Spring's decoupled design makes it rather easy to implement. Here's code I wrote to implement RESTful dispatches using Spring MVC.(Also available as a download here)
package com.yellowfish.servlets; import javax.servlet.http.*; import org.apache.log4j.*; import java.util.*; import org.springframework.web.servlet.mvc.multiaction.*; public class RESTMethodResolver implements MethodNameResolver { public String getHandlerMethodName(HttpServletRequest req) throws NoSuchRequestHandlingMethodException { Logger log = Logger.getLogger("com.yellowfish.servlets"); log.debug("Resolving method name for the Request"); String method = req.getParameter("_method"); String id = req.getParameter("id"); String http_method = req.getMethod().toUpperCase(); String controller_method = null; log.debug("method: "+method+" http_method: " + http_method + " id: "+id); if(http_method.equals("GET")) { String uri = req.getRequestURI(); controller_method = (uri.endsWith("/new") ? "_new" : "show"); if(controller_method == "show") { controller_method = (id == null) ? "index" : "show"; } } else if(http_method.equals("POST")) { if(method != null) { method = method.toUpperCase(); if(id == null) throw new com.yellowfish.servlets.ServletException("id cannot be NULL for PUT and DELETE"); if (method.equals("PUT")) controller_method = "update"; else if(method.equals("DELETE")) controller_method = "delete"; } else { controller_method = "create"; } } if(controller_method == null) { log.debug("No Controller Method Found"); throw new NoSuchRequestHandlingMethodException(null, this.getClass()); } log.debug("Controller method resolved to :" + controller_method); req.setAttribute("controller_method_name", controller_method); if(id != null) { try { req.setAttribute("model-id", Long.valueOf(id)); } catch(NumberFormatException exp) { log.warn("id" + id + " is not a Number"); } } return controller_method; } }
Then simply declare this bean in the spring config:
<bean class="com.yellowfish.servlets.RESTMethodResolver" id="rest-method-resolver"></bean>
It resolves incoming URL and Method as per following table:
| URI | GET/POST | ID Parameter Present? | _method Parameter Present? | Method Name |
|---|---|---|---|---|
| /server | GET | No | N/A | index |
| /server/_new | GET | No | N/A | new |
| /server?id=100 | GET | Yes | N/A | show |
| /server | POST | No | No | create |
| /server | POST | Yes | PUT | update |
| /server | POST | Yes | DELETE | delete |
To make life simple, the code above assumes all IDs to be numeric and if ID is present in incoming request, it creates a Request attribute called 'model-id' .
