Ich versuche, eine RESTful Controller mit Frühling 3.0. Der Controller ist für eine Verwaltungs-API für eine Portalanwendung gedacht. Die Operationen, die ich durchführen möchte, sind:
- GET /api/portals zum Auflisten aller Portale
- POST /api/portals zum Erstellen eines neuen Portals
- GET /api/portals/{id} zum Abrufen eines vorhandenen Portals
- PUT /api/portals/{id} zur Aktualisierung eines bestehenden Portals
- DELETE /api/portal/{id} zum Löschen eines bestehenden Portals
Nachdem ich den Controller wie unten dargestellt kommentiert habe, stelle ich fest, dass die Operationen zum Auflisten aller Portale oder zum Erstellen eines neuen Portals nicht zugeordnet werden.
Meine Fragen lauten also:
- Habe ich die Klasse richtig kommentiert?
- Befolge ich die richtigen Konventionen für die Implementierung eines RESTful-Webdienstes?
- Könnte im Frühling etwas kaputt sein?
Der nachstehende Codeauszug zeigt, wie ich meine Klasse mit Anmerkungen versehen habe:
@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";
}
.
.
}
Beim Start sehe ich, dass Spring die Endpunkte registriert hat:
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]
Aber wenn ich versuche, meine API mit cURL aufzurufen
curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals/
o
curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals
Ich erhalte die folgenden Fehler:
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'
Ich habe das gleiche Problem, wenn ich versuche, eine Datei zu erstellen:
curl -F ...... --request POST http://localhost:8080/com.btmatthtews.minerva/api/portals
Wenn Sie jedoch versuchen, eine vorhandene Ressource zu bearbeiten (abrufen, aktualisieren oder löschen), funktioniert dies problemlos.
Aktualisierung: Die Lösung fand sich in einem Kommentar von @axtavt . Ich habe <url-pattern>/api/*</url-pattern> in meiner web.xml Servlet-Zuordnung verwendet. Es musste in <url-pattern>/</url-pattern> geändert werden.