2010-02-19 11 views
6

Sto cercando di creare un controller RESTful utilizzando Spring 3.0. Il controller è per un'API di gestione per un'applicazione portale. Le operazioni che voglio eseguire sono:Come configurare un controller RESTful in Spring 3 con annotazioni?

  • GET/api/portali per elencare tutti i portali
  • POST/api/portali per creare un nuovo portale
  • GET/api/portali/{id} per recuperare un portale
  • PUT/api/portali/{id} esistente per aggiornare un portale
  • DELETE/api/portale/{id} esistente per eliminare un portale

esistente Dopo annotare il contr come illustrato di seguito, trovo che le operazioni per elencare tutti i portali o creare un nuovo portale non vengano mappate.

Quindi le mie domande sono:

  • Ho io annotato correttamente la classe?
  • Sto seguendo le convenzioni corrette per l'implementazione di un servizio Web RESTful?
  • Potrebbe esserci qualcosa di rotto in primavera?

L'estratto di codice seguente mostra come ho annotato la mia classe:

@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"; 
    } 

    . 
    . 
} 

Durante l'avviamento Sto vedendo che le cose primavera ha registrato gli end-point:

2010-02-19 01:18:41,733 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/] onto handler [[email protected]1717f] 
2010-02-19 01:18:41,734 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}] onto handler [[email protected]1717f] 
2010-02-19 01:18:41,734 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}.*] onto handler [[email protected]1717f] 
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}/] onto handler [[email protected]1717f] 
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals] onto handler [[email protected]1717f] 
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals.*] onto handler [[email protected]1717f] 

Ma quando provo a invocare la mia API usando cURL

curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals/ 

o

curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals 

Ottengo i seguenti errori:

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' 

ottengo lo stesso problema quando provo a fare un creare:

curl -F ...... --request POST http://localhost:8080/com.btmatthtews.minerva/api/portals 

Ma se provate a operare su una esistente risorsa (recuperare, aggiornare o eliminare) funziona bene.

Aggiornamento: La soluzione è stata fornita in un commento @axtavt. Stavo usando < url-pattern >/api/* </url-pattern > nella mia mappatura servlet web.xml.Aveva bisogno di essere cambiato a < url-pattern >/</url-pattern >

+0

Si potrebbe voler rimuovere il valore = "/" nell'elenco, creare metodi. potrebbe confondere il resolver url. un'altra cosa che ho notato è un problema con i namespace. i metodi sono mappati a "com.btmatthews.mars" e ricevi degli errori per "com.btmatthews.minerva" – giladbu

+0

Prendendo il valore = "/" non ha fatto alcuna differenza ma quando ho provato ho visto che lo stesso URL i mapping sono stati registrati, quindi lo rimuoverò comunque. Il nome del pacchetto per i componenti del portale è com.btmatthews.mars ... ma l'applicazione costruita su di esso è impacchettata in com.btmatthews.minerva .... La sua confusione ma non un problema. –

+5

L'unica possibilità che posso vedere è "" di DispatcherServlet errato. Per questa configurazione dovrebbe essere '/'. – axtavt

risposta

0

L'URL di pubblicare nel vostro ricciolo estratto

http://localhost:8080/portal/api/portals 

non corrisponde l'URL nella avvertimento primavera

/com.btmatthews.minerva.portal/api/portals 

Senza sapere come viene configurata la tua webapp, quale percorso di contesto è, come appare il contesto di Spring, ecc., È piuttosto difficile da diagnosticare ma questo mi sembra un grande indizio.

+0

La corretta root di contesto era /com.btmatthews.minerva.portal piuttosto portale. Ho aggiornato la domanda originale. –

4

Controlla il url-pattern nel tuo web.xml e confrontalo con il tuo argomento di ricciolo.

Here is an example Ho scritto che ti guida attraverso l'intero processo MVC di primavera.

0

Hai fatto pochi errori.

@RequestMapping(value = "/", method = RequestMethod.GET) 

public String listPortals(final Model model) 
{ 
} 

Qui il metodo deve accettare qualche parametro Modello, ma non viene passato. è necessario scrivere questo metodo all'interno. o se vuoi passare questo, devi inviarlo come variabile del percorso o come parametro Param.

@RequestMapping(value = "/{id}", method = RequestMethod.GET) 

public String getPortal(@PathVariable("id") 

qui la sintassi corretta è @PathVariable(value="id")

E se questo non funziona quindi provare questo:

@RequestMapping(value = "/SOMETHING", method = RequestMethod.GET) 
+1

Generalmente non è utile rispondere a domande così vecchie, soprattutto quando la domanda è stata aggiornata con la soluzione. – zchrykng

0

In Spring 3, il controller resto non è altro che un controller normale (@Component) e l'unica differenza è che un controller Rest restituisce JSON/XML invece di "Views". Quindi penso che tu stia andando bene rispetto alle annotazioni. Tuttavia, due cose mancanti che non riesco a vedere: 1- Ogni metodo deve avere un valore "produrre" (per la negoziazione del contenuto): @RequestMapping (value = "/ {id}", metodo = RequestMethod.GET, produce = "application/json")

2- È necessario un ObjectMapper di qualche tipo (ad esempio Marshaller e Unmarshaller) per poter mappare oggetti a JSON/XML e viceversa. Questi due dovrebbero essere nella configurazione del servlet, invece di configurare un risolutore di viste. E dovrebbe essere così.

Problemi correlati