null

Разбираемся с типами ссылок в JSF

Сегодня поговорим о ссылках. Тех самых по которым мы кликаем, когда хотим перейти с одной страницы сайта на другую. 

Мы постоянно на что-то кликаем. Кликаем тут, кликаем там. Открываем сотни, а то и тысячи страниц за день. А ещё мы постоянно открываем новые вкладки в браузере. Сайты, которыми мы пользуемся сегодня уже не представляют собой набор статических страниц. Или даже набор страниц, содержимое которых генерируется на сервере. AJAX сейчас витает повсюду. И иногда мы, разработчики, очень косячим. Получается очень неприятная с точки зрения UX пользвователя ситуация. Он хочет кликнуть по ссылке и открыть её в новой вкладке, но он не может этого сделать. Ибо ссылка или кнопка работают по технологии AJAX. Они идут на сервер, что-то там делает, а он уже возвращает ссылку куда переходить. Очень часто на разных сайтах приходится сталкиваться с таким. При этом регулярно, запрет перейти на эту страницу сразу без запроса на сервер является необоснованным.

Грешил и я таким. Несколько раз делал ссылки на странице работающие через AJAX. И это был функционал, которым я сам в ходе разработки пользовался сотню раз за день. В какой-то момент меня уже начало это сводить с ума. Я просто хочу зажать на клавиатуре клавишу CTRL и открыть ссылку в новой вкладке. Психика не выдержала и я пошёл разбираться, что я сделал не так. Ведь этот интерфейс я реализовал сам.

Написано приложение на JSF. И рассказ пойдет о его компонентах. Сделать ссылку в JSF можно с помощью нескольких разных компонентов. Но разница между ними  у меня в голове почему-то сидела не очень чётко. Когда мне нужно было добавить новую ссылку, я не особо задумывался и использовал тот компонент, который вспоминался первым. А зря. Сейчас расскажу кто из них, что значит и когда их применять.

Знакомимся с нашими героями:

  1. <h:link value = "Кликай сюда!" outcome = "page2">
    
  2. <h:outputLink value="/blogs/bleizard">Переход к блогу пользователя Bleizard</h:outputLink>
    
  3. <h:commandLink action="#{myBean.method} value="Очередная ссылка"/>

     

Итого. У нас 3 разных способа создания обычной ссылки. Любой из этих компонентов может использоваться для того чтобы обернуть в ссылку не только текст, но и изображение или любой другой компонент. Для этого просто нужно убрать с него атрибут outcome или value. в зависимости от используемого, и вставить нужное содержимое внутрь тега ссылки. Теперь переходим к разнице между этими компонентами и когда лучше их использовать.

Тег <h:link>  генерирует обычную html ссылку с URL в атрибуте href. Появился этот тег в JSF 2. Он служит для того, чтобы делать внутренние переходы между страницами приложения. Тег a генерируется вместе с href в момент формирования страницы на сервере. Получив страницу, клиент может сделать переход по ссылке без дополнительных запрсоов к серверу. А следовательно и открыть средставим браузера ссылку в новой вкладки.

Тег <h:outputLink> также преобразуется в обычную HTML ссылку. Отличие от предыдущего тега в том, что здесь нельзя в качестве значения для перехода указать идентификатор представления в JSF. Обязательно нужно указывать именно URL. Этот компонент следуюет использовать для перехода на внешние ресурсы.

Последний тег <h:commandLink>. Он служит для вызова метода на сервере по средством AJAX запроса. Соответственно, атрибута href адекватного у этой ссылки нет. На ней будет обработчик события onClick. При нажатии сработает javascript функция, которая сформирует запрос к серверу и вызовет наш Java метод. Если этот метод вернёт какую-нибудь не пустую строку, то при обработке ответа на стороне клиента будет совершён переход. Как видно из описания  этот компонент не позволит сделать удобной навигацию между страницами. Но он служит совершенно не для этого. Он нужен, когда мы можем определить куда делать и делать ли вообще переход после того, как выполнить некоторый код бизнес логики. Например, этот функционал, нужен когда вы хотите сделать в форме кнопку сохранить. При нажатии браузер сначала сделает запрос на сервер, передаст заполненную форму, на основе этих данных сгенерирует ссылку (например попутно сделая запрос к БД), а потом уже сможет вернуть эту ссылку. Ключевое здесь то, что ссылку нельзя сгенерировать в момент обращения к странице. 

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

На этом, пожалуй, откланяюсь!