Статьи

Интеграция Spring и JSF: динамическая навигация

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

1
<h:commandButton action="#{bean.actionBasedOnAge}"/>
1
2
3
4
5
6
7
public String actionBasedOnAge() {
  if(age &lt; 12) {
    return "fetchadult";
  } else {
    return "ok"
  }
}

В приведенном выше примере показано, как любое лицо младше двенадцати лет направляется на 'fetchadult' вместо обычного 'ok' . Для результатов 'fetchadult' и 'ok' должны быть определены правила навигации в 'fetchadult' faces-config.xml чтобы JSF знал, какую именно страницу отображать.

При работе с Spring MVC часто более естественно иметь логику навигации, содержащуюся в @Controller компоненте @Controller . Чтобы помочь с этим, при рендеринге JSF из MVC доступны неявные переменные 'controller' и 'handler' . Переменная 'controller' предоставляет доступ к bean-компоненту контроллера, который был сопоставлен с исходным запросом, а переменная 'handler' к подчиненному обработчику MVC. В Spring 3.0 'controller' и 'handler' как правило, являются одним и тем же объектом. В Spring 3.1, однако, базовая архитектура MVC изменяется, и 'handler' обычно будет экземпляром org.springframework.web.method.HandlerMethod .

Вот кнопка отправки, которая ссылается на someNavigation() @Controller :

1
<h:commandButton action="#{controller.someNavigation"/>

Хотя доступ к компоненту контроллера полезен, это не идеальное решение. Я предпочитаю использовать логические имена на моих страницах JSF и отображать эти методы Java. Я также хочу простой способ вернуться к данным базовой модели.

Аннотация @NavigationMapping предоставляет другой, более гибкий подход к обработке навигации. Он работает очень похоже на @RequestMappings . Аннотация может быть размещена в любом открытом методе вашего @Controller для сопоставления результатов навигации с пунктами назначения.

1
<h:commandButton action="submit"/>
1
2
3
4
@NavigationMapping
public String onSubmit() {
  return "redirect:http://www.springsource.org";
}

Если вам нужен доступ к компоненту @Value можно использовать стандартную аннотацию Spring @Value . Любое выражение EL, которое может разрешить страница, также может использоваться в параметре метода навигации.

1
2
3
4
@NavigationMapping
public String onSubmit(@Value("#{person.age}") int age) {
...
}

Доступ к элементам модели еще проще. Пока у вас есть только один объект того типа, к которому вы хотите получить доступ в вашей модели, и это не простой тип (int, String и т. Д.), Вам не нужны аннотации:

1
2
3
4
@NavigationMapping
public String onSubmit(Person p) {
...
}

Также можно использовать другие типы аргументов (полный список см. В JavaDoc). Например, вот навигационное отображение, которое обрабатывает результаты 'submit' , 'cancel' и 'save' . Введенные аргументы сообщают нам, какой из трех результатов был выбран, и предоставляют доступ к исходному UIComponent .

1
2
3
4
@NavigationMapping('submit','cancel','save')
public String handleNavigation(String outcome, UIComponent source) {
...
}

Типы возврата также одинаково гибки. Вы можете возвращать имена представлений в виде String , вы также можете использовать ту же нотацию "@hotelsController.show" о которой я ранее писал в блоге . Вы также можете возвращать object View напрямую или использовать NavigationOutcome если хотите включить неявные элементы модели.

И, наконец, если вы просто хотите сделать немедленный ответ, вы можете использовать аннотацию @ResponseBody или вернуть HttpEntity . Это работает точно так же, как Spring.

Ссылка: Интеграция Spring & JavaServer Faces: Динамическая навигация от нашего партнера JCG Филиппа Вебба в блоге Фила Вебба в блоге.