Note that there are some explanatory texts on larger screens.

plurals
  1. POHow configure a RESTful controller in Spring 3 with annotations?
    text
    copied!<p>I am trying to create a <a href="http://en.wikipedia.org/wiki/RESTful" rel="nofollow noreferrer">RESTful</a> controller using <a href="http://www.springsource.org/about" rel="nofollow noreferrer">Spring</a> 3.0. The controller is for a management API for a portal application. The operations I want to perform are:</p> <ul> <li>GET /api/portals to list all the portals</li> <li>POST /api/portals to create a new portal</li> <li>GET /api/portals/{id} to retrieve an existing portal</li> <li>PUT /api/portals/{id} to update an existing portal</li> <li>DELETE /api/portal/{id} to delete an existing portal</li> </ul> <p>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. </p> <p>So my questions are:</p> <ul> <li>Have I annotated the class correctly?</li> <li>Am I following the correct conventions for implementing a RESTful web service?</li> <li>Might there be something broken in Spring?</li> </ul> <p>The code extract below shows how I have annotated my class:</p> <pre><code>@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&lt;String, String&gt; 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&lt;String, String&gt; 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"; } . . } </code></pre> <p>During start-up I am seeing that Spring things it has registered the end-points:</p> <pre><code>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] </code></pre> <p>But when I try to invoke my API using cURL </p> <pre><code>curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals/ </code></pre> <p>or</p> <pre><code>curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals </code></pre> <p>I get the following errors:</p> <pre><code>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' </code></pre> <p>I get the same problem when I try to do a create:</p> <pre><code>curl -F ...... --request POST http://localhost:8080/com.btmatthtews.minerva/api/portals </code></pre> <p>But if try to operate on an existing resource (retrieve, update or delete) it works okay.</p> <p><strong>Update:</strong> The solution was provided in a comment by <a href="https://stackoverflow.com/users/103154/axtavt">@axtavt</a>. I was using &lt;url-pattern&gt;/api/*&lt;/url-pattern&gt; in my web.xml servlet mapping. It needed to be changed to &lt;url-pattern&gt;/&lt;/url-pattern&gt;</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload