2010-02-19 13 views
6

Próbuję utworzyć kontroler RESTful przy użyciu Spring 3.0. Kontroler służy do zarządzania API dla aplikacji portalu. Operacje, które chcę wykonać to:Jak skonfigurować kontroler RESTful w Spring 3 z adnotacjami?

  • GET/api/portale notować wszystkie portale
  • POST/api/portale, aby utworzyć nowy portal
  • GET/api/portale/{id} na odzyskać istniejący portal
  • PUT/API/portale/{id}, aby zaktualizować istniejący portal
  • usuwanie/api/portalu/{id}, aby usunąć istniejący portal

Po adnotacji kontr oller, jak pokazano poniżej, uważam, że operacje polegające na wylistowaniu wszystkich portali lub utworzeniu nowego portalu nie są mapowane.

Więc moje pytania to:

  • Czy ja odnotowany klasy poprawnie?
  • Czy postępuję zgodnie z prawidłowymi konwencjami dotyczącymi implementacji usługi RESTful?
  • Może być coś złamanego na wiosnę?

Ekstrakt kod poniżej pokazuje, jak mam odnotowany moją klasę:

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

    . 
    . 
} 

Podczas rozruchu widzę, że rzeczy Wiosną zarejestrował końcowych punktów:

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] 

Ale kiedy próbuję wywołać mój interfejs API przy użyciu cURL

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

lub

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

otrzymuję następujące błędy:

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' 

uzyskać ten sam problem, gdy próbuję zrobić utworzyć:

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

Ale jeśli starają się działać na istniejącym zasób (pobierz, zaktualizuj lub usuń) działa poprawnie.

Aktualizacja: Rozwiązanie zostało dostarczone w komentarzu przez @axtavt. W moim mapowaniu serwletu web.xml użyłem wzoru adresu URL < url-pattern >/api/* </url-pattern >.To musiał być zmieniony na < url-pattern >/</url-pattern >

+0

Możesz usunąć wartość = "/" na liście, utwórz metody. może zmylić przelicznik adresów URL. Kolejną rzeczą, którą zauważyłem, jest problem z przestrzeniami nazw. metody są mapowane na "com.btmatthews.mars" i pojawiają się błędy dla "com.btmatthews.minerva" – giladbu

+0

Wypisywanie wartości = "/" nie miało znaczenia, ale kiedy przetestowałem, zobaczyłem, że ten sam URL mapowania zostały zarejestrowane, więc i tak go usunę. Nazwa pakietu komponentów portalu to com.btmatthews.mars ... ale aplikacja zbudowana na nim jest spakowana w com.btmatthews.minerva .... To jest mylące, ale nie stanowi problemu. –

+5

Jedyną możliwością, którą mogę zobaczyć, jest błędne '' DispatcherServlet '. Dla tej konfiguracji powinien to być "/". – axtavt

Odpowiedz

0

URL piszesz w swoim curl wypis

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

nie pasuje do adresu URL w ostrzeżeniu wiosennym

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

Nie wiadomo, jak skonfigurowana jest twoja aplikacja, jaka jest ścieżka kontekstu, jak wygląda kontekst wiosenny itd., Jest trudna do zdiagnozowania, ale to brzmi dla mnie jak wielka wskazówka.

+0

Prawidłowym kontekstowym katalogiem głównym był portal /com.btmatthews.minerva.portal raczej. Zaktualizowałem oryginalne pytanie. –

4

Podwójne sprawdzenie url-pattern w swoim web.xml i porównanie go z argumentem curl.

Here is an example Napisałem, który przeprowadzi Cię przez cały proces Spring MVC.

0

Zrobiłeś kilka błędów.

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

public String listPortals(final Model model) 
{ 
} 

Tutaj metoda musi zaakceptować jakiś parametr Model, ale to nie jest przekazywane. musisz napisać tę metodę wewnętrzną. lub jeśli chcesz to przekazać, musisz wysłać go jako zmienną ścieżki lub jako Param.

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

public String getPortal(@PathVariable("id") 

tutaj poprawna składnia jest @PathVariable(value="id")

A jeśli to nie zadziała następnie spróbuj tego:

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

Generalnie nie jest pomocne udzielanie odpowiedzi na tak stare pytania, zwłaszcza gdy pytanie zostało zaktualizowane za pomocą rozwiązania. – zchrykng

0

Wiosną 3, kontroler Reszta jest nie więcej niż zwykły kontroler (@ Component) i jedyną różnicą jest to, że kontroler Rest zwraca JSON/XML zamiast "Widoki". Myślę więc, że postępujesz właściwie w odniesieniu do adnotacji. Jednak dwie rzeczy, których nie widzę: 1- Każda metoda musi mieć wartość "produce" (dla negocjacji treści): @RequestMapping (value = "/ {id}", method = RequestMethod.GET, produkuje = "application/json")

2- Potrzebujesz obiektu ObjectMapper jakiegoś typu (np. Marshaller i Unmarshaller), aby móc mapować obiekty do JSON/XML i na odwrót. Te dwa powinny znajdować się w twojej konfiguracji serwletów, zamiast konfigurować resolwera widoku. A to powinno być to.

Powiązane problemy