2015-10-08 16 views
8

Mam obecnie projekt wykorzystujący kontroler Spring i Thymeleaf do stworzenia małej aplikacji przeglądarki. Klasa kontroler jest zadeklarowana jakoWiosna MVC, Thymeleaf i REST

@Controller public class MyController { 

wewnątrz sterownika mam GET zdefiniowany jako

@RequestMapping(value = "/foobars", method = RequestMethod.GET) 
String index(Model model, --- more params ---) { 
    //call repository and get foobarsList 
    //model.addAttribute("foobars", foobarsList); 
      ... 
    return "foobars/foobarThymeleafTemplate" 
} 

The połączenia repozytorium i dostać foobarList jest wezwaniem do MongoRepository zdefiniowany jako:

public interface FoobarRepository extends MongoRepository< ... cut for brevity> { 

    @RestResource(rel = "by-id") 
    Marker findMarkerById(String id); 

    ... additional @RestResources cut for brevity ... 
} 

Znowu Br Owser App wygląda świetnie. The GET wywołuje repozytorium, zapełniając model z listą foobarów i Thymeleaf robi to z tą listą.

PROBLEM: Teraz potrzebuję aby uzyskać dostęp do tych samych danych z Android App i wolałbym użyć spoczynku i po prostu zużywają JSON w aplikacji Android. Chcę zachować Thymeleaf, ale w razie potrzeby zmienię aplikację przeglądarki.

PYTANIE: Czy istnieje sposób, aby w jakiś sposób korzystać z tego samego @Controller albo będę musiał utrzymać drugą FoobarRestController korzystając @RestController z/restFoobars końcowych? Drugi kontroler REST działa na pewno, ale wydaje się nieco niechlujny ... słaby projekt.

Twoje myśli i rekomendacje?

Jeszcze raz dziękuję. -Rich

Odpowiedz

1

Mój preferowanym podejściem jest tu użyć dziedziczenia:

@RequestMapping('/foobars') 
abstract class FoobarBaseController { 

    @RequestMapping 
    abstract listAll() 
} 

@Controller 
class FoobarHtmlController extends FoobarBaseController { 
    @Override ModelAndView listAll() { 
     new ModelAndView('foobars/foobarThymeleafTemplate', [foobars: foobarsList]) 
    } 
} 

@RestController 
@RequestMapping('/foobars', produces = MediaType.APPLICATION_JSON_VALUE) 
class FoobarJsonController extends FoobarBaseController { 
    @Override Collection<Foobar> listAll() { 
     foobarsList 
    } 
} 

Alternatywnie, jeśli istnieje znacząca praca do wykonania kontroli wejść i tym podobne, można zaimplementować że w BaseController i mają abstract listAllResponse(DomainObject foo) że następnie zwraca odpowiedni ModelAndView (HTML) lub DTO (JSON).

Jedna pułapka tego podejścia jest to, że nie można zastąpić tylko część @RequestMapping, więc trzeba powtórzyć klasę część mapowania gdy podasz parametr produces, ale można dziedziczyć metody poziomie mapowania bez problemu.

1

Expose CRUD Crud

Użyj @Controller zrobić pracę obsługi strony HTML i korzystania z repozytorium można narazić podmiot poprzez API REST dla podstawowych czynności, takich jak CRUD za pomocą SPRING-DATA-REST narażać swoich podmiotów. Myślę, że już robi patrząc na kod

@RestResource(rel = "by-id") 
    Marker findMarkerById(String id); 

Expose logiki biznesowej

Jeśli chcesz wystawiać żadnej logiki biznesowej, trzeba stworzyć Service warstwę i po prostu nazwać pośrednictwem @Controller dla strony internetowej.i utworzyć kolejny kontroler jako @RestController dla interfejsu web API.

Możesz zauważyć, że nie powielasz tutaj żadnego kodu, ponieważ logika jest zapisana w pojedynczym punkcie warstwy Usługi. Ale używanie różnych kontrolerów do różnych celów.

Ponieważ nie trzeba całą logikę w stronie internetowej, aby uzyskać narażone na API, stosowanie oddzielnego sterownika dla odpoczynku może być czysta realizacja projektu dla kodu, jeśli można obszaru nazw swój kod jako app.web i app.api.

Food for thought

użyć pełną realizację REST API dla stron i Android. Następnie użyj AngualarJS lub backboneJs, aby wykonać implementację po stronie klienta za pomocą HTML5. Myślę, że to jest przyszłość.

+0

mimo, że odpowiedziałeś na to dwa lata temu, i zgadzam się na używanie kompletnego api do odpoczynku na zapleczu, a następnie użycie ram javascript dla interfejsu użytkownika powinno być logiczne, do czego społeczność powinna dążyć, jednak wciąż nie ma prawie żadnych pytań na stackoverflow i nadal prawie nie ma dokumentacji lub samouczków, jak to zrobić, albo społeczność Java jest bardzo odporna na zmiany, albo to po prostu nie działa tak dobrze na dłuższą metę, co o tym myślisz? –