I am trying to create a RESTful controller using Spring 3.0. The controller is for a management API for a portal application. The operations I want to perform are:
After annotating the controller as illustrated below I find the the operations to list all the portals or create a new portal do not get mapped.
So my questions are:
The code extract below shows how I have annotated my class:
@Controller
@RequestMapping("/api/portals")
public final class PortalAPIController
{
private final static Logger LOGGER = LoggerFactory.getLogger(PortalAPIController.class);
@RequestMapping(value = "/", method = RequestMethod.GET)
public String listPortals(final Model model)
{
PortalAPIController.LOGGER.debug("Portal API: listPortals()");
.
.
return "portals";
}
@RequestMapping(value = "/", method = RequestMethod.POST)
public String createPortal(@RequestBody final MultiValueMap<String, String> portalData, final Model model)
{
PortalAPIController.LOGGER.debug("Portal API: createPortal()");
.
.
return "portal";
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String getPortal(@PathVariable("id") final String portalId, final Model model, final HttpServletResponse response)
throws IOException
{
PortalAPIController.LOGGER.debug("Portal API: getPortal()");
.
.
return "portal";
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public String updatePortal(@PathVariable("id") final String portalId,
@RequestBody final MultiValueMap<String, String> portalData, final Model model, final HttpServletResponse response)
throws IOException
{
PortalAPIController.LOGGER.debug("Portal API: updatePortal()");
.
.
return "portal";
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public String deletePortal(@PathVariable("id") final String portalId, final Model model, final HttpServletResponse response)
throws IOException
{
PortalAPIController.LOGGER.debug("Portal API: deletePortal()");
.
.
return "portal";
}
.
.
}
During start-up I am seeing that Spring things it has registered the end-points:
2010-02-19 01:18:41,733 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,734 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,734 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}.*] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}/] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals.*] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
But when I try to invoke my API using cURL
curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals/
or
curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals
I get the following errors:
2010-02-19 01:19:20,199 WARN [org.springframework.web.servlet.PageNotFound] - No mapping found for HTTP request with URI [/com.btmatthews.minerva.portal/api/portals] in DispatcherServlet with name 'portal'
2010-02-19 01:19:32,360 WARN [org.springframework.web.servlet.PageNotFound] - No mapping found for HTTP request with URI [/com.btmatthews.minerva.portal/api/portals/] in DispatcherServlet with name 'portal'
I get the same problem when I try to do a create:
curl -F ...... --request POST http://localhost:8080/com.btmatthtews.minerva/api/portals
But if try to operate on an existing resource (retrieve, update or delete) it works okay.
Update: The solution was provided in a comment by @axtavt. I was using <url-pattern>/api/*</url-pattern> in my web.xml servlet mapping. It needed to be changed to <url-pattern>/</url-pattern>
Spring RestController annotation is a convenience annotation that is itself annotated with @Controller and @ResponseBody . This annotation is applied to a class to mark it as a request handler. Spring RestController annotation is used to create RESTful web services using Spring MVC.
The @API annotations as per the documentation states “The annotation @Api is used to configure the whole API, and apply to all public methods of a class unless overridden by @APIMethod”. Note the words unless overridden. Often you find that you casually go ahead and mark a class with @API.
One of the most important annotations in spring is the @RequestMapping Annotation which is used to map HTTP requests to handler methods of MVC and REST controllers. In Spring MVC applications, the DispatcherServlet (Front Controller) is responsible for routing incoming HTTP requests to handler methods of controllers.
Double check the url-pattern
in your web.xml
and compare it to your curl argument.
Here is an example I wrote which walks you through the whole Spring MVC process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With