Как мне реализовать фронт-контроллер в Java?

Я пишу очень простой веб-фреймворк с использованием Java-сервлетов в учебных целях. Я делал это раньше в PHP, и он работал, обращаясь к URI запроса, а затем создавая соответствующий класс и метод.

Это работало нормально в PHP, так как можно сделать что-то вроде $c = new $x; $x->$y;, Однако я не уверен, как перевести это на Java или даже если это подходящий способ сделать это.

Пока что я пробовал:

Router router = new Router(request.getPathInfo());
String className = router.route(); //returns com.example.controller.Foo

Class c = Class.forName(className);
Object x = c.newInstance();

Foo y = (Foo) x;
y.doSomething();

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

Как я должен заставить это работать?

4 ответа

Я бы использовал Servlet Filter в качестве фронт-контроллера. Маршрутизатор будет соединять пути с диспетчерами запросов. В методе doFilter вы должны преобразовать ServletRequest в HttpServletRequest, извлечь путь запроса и сопоставить его с зарегистрированными сопоставлениями. Результатом этого сопоставления является диспетчер запросов, с которым вы бы отправляли запрос.

В псевдокоде:

doFilter(ServletRequest request, ServletResponse response) {
  httpServletRequest = (HttpServletRequest) request;
  path = httpServletRequest.getRequestURI();
  dispatcher = router.getTarget(path);
  dispatcher.dispatch(request, response);
}

В зависимости от ваших потребностей может быть достаточно стандартного механизма маршрутизации Servlet API.

Захватить действия в Map<String, Action> где String Ключ представляет собой более или менее комбинацию метода запроса и запроса pathinfo. Я уже публиковал подобный ответ здесь: Java Front Controller

Вы можете заполнить такую ​​карту либо статически (жестко закодировать все действия), либо динамически (соглашение о конфигурации, поиск классов в определенном пакете, или сканирование всего пути к классам для классов с определенной аннотацией или реализация определенного интерфейса).

И просто придерживайтесь Servlet. Фильтр не существует для. При максимальном использовании используйте его для отправки запроса сервлету контроллера. В сервлете просто реализуем HttpServlet#service(),

Не совсем уверен, что вы ищете, но вы можете взглянуть на Java-сервлеты. Конечно, многие веб-фреймворки абстрагируются от простых сервлетов, но это очень хорошее место, чтобы начать изучать веб-приложения на Java, если вы спросите меня (что вы косвенно сделали;))

Загрузите спецификацию Java-сервлета здесь: Java Servlet Spec - это довольно интересно.

Как вы должны заставить это работать? Однако вы хотите этого. Если вы просто делаете это в учебных целях, все, что вы делаете, будет хорошо.

Я бы посоветовал, чтобы все ваши действия реализовывали один и тот же интерфейс (возможно, расширяя Servlet), чтобы вам не приходилось компилировать во всех разных классах.

Тогда вы можете делать то, что делаете, за исключением того, что Foo становится актером Servlet и тогда вам не нужно иметь особый случай для всех ваших разных классов.

Затем вы также можете загрузить маршруты из конфигурации (возможно, XML-файл).

По сути, то, что вы делаете, реализовано инфраструктурой Struts 1, так что, возможно, стоит почитать об этом (это открытый исходный код, поэтому вы также можете посмотреть на источник, если хотите).

Другие вопросы по тегам