2015-10-08 8 views
8

У меня в настоящее время есть проект с помощью контроллера Spring и Thymeleaf для создания небольшого приложения для браузера. Класс контроллера объявленSpring MVC, Thymeleaf & REST

@Controller public class MyController { 

Внутри контроллера У меня есть ПОЛУЧИТЬ определяется как

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

В хранилище вызовов и получить foobarList призыв к MongoRepository определяется как:

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

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

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

Опять же, броузер er App выглядит великолепно. GET вызывает репозиторий, заполняет модель со списком foobars и Thymeleaf делает это с этим списком.

ПРОБЛЕМА: Теперь мне нужно получить доступ к этим же данным из Android App, и я предпочел бы использовать REST и просто потреблять JSON в Android App. Я хочу сохранить Thymeleaf, но при необходимости реорганизует приложение браузера.

ВОПРОС: Есть ли способ, чтобы каким-то образом использовать тот же @Controller или мне придется поддерживать вторую FoobarRestController используя @RestController с/restFoobars конечными точками? Второй контроллер REST работает наверняка, но, похоже, это небрежный ... плохой дизайн.

Ваши мысли и рекомендации?

Еще раз спасибо. -Rich

ответ

1

Мой предпочтительный подход здесь заключается в использовании наследования:

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

В качестве альтернативы, если есть значительная работа предстоит сделать проверки входов и т.п., вы можете реализовать, что в BaseController и имеют abstract listAllResponse(DomainObject foo) что затем возвращает соответствующие ModelAndView (HTML) или DTO (JSON).

Один ловушкой этого подхода заключается в том, что вы не можете изменить только часть @RequestMapping, так что вам придется повторять часть этого класса, отображения при указании параметра produces, но вы можете наследовать метод уровня сопоставления без проблем.

1

Expose Crud

@Controller Используйте, чтобы сделать работу обработки HTML-страницы и при помощи Repository вы можете выставить объект через REST API для основных действий, таких как падла, используя SPRING-DATA-REST выставить свои объекты. Я думаю, что вы уже делаете это, глядя на код

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

Expose бизнес-логики

Если вы хотите, чтобы выставить любую бизнес-логику, вы должны создать Service слой и просто вызовите его через ваш @Controller для веб-страницы.и создать другой контроллер как @RestController для интерфейса веб-интерфейса.

Вы можете заметить, что вы не дублируете код здесь, так как логика написана в единственной точке уровня сервиса. Но использование разных контроллеров для разных целей.

Как вам не нужна вся логика в вебе-странице, чтобы получить подвергается API, использование отдельного контроллера для REST может быть чистой реализацией дизайна для вашего кода, если вы можете пространство имен коды, как app.web и app.api.

Пища для размышлений

Используйте полную реализацию REST API для веб-страниц и андроида. Затем используйте AngualarJS или backboneJs, чтобы выполнить реализацию на стороне клиента с помощью HTML5. Я думаю, что это будущее.

+0

Если вы ответили это два года назад, и я согласен с использованием полного отдыха api для задней части, а затем использование фреймворка javascript для переднего конца должно логически быть тем, к чему должно стремиться сообщество, однако вопросов по-прежнему почти нет в stackoverflow и практически без документации или учебников о том, как это сделать, либо сообщество Java очень сопротивляется изменению, либо это просто не так хорошо работает в долгосрочной перспективе, как вы думаете? –

Смежные вопросы