Различия между действием и actionListener



В чем разница между action и actionListener и когда я должен использовать action и actionListener?

816   3  

3 ответов:

actionListener

использовать actionListener если вы хотите иметь крючок до реальное бизнес-действие выполняется, например, для его регистрации и / или для установки дополнительного свойства (by <f:setPropertyActionListener>), и / или иметь доступ к компоненту, который вызвал действие (который доступен по ActionEvent. Если бы они отсутствовали, Эл смущенно бросил бы javax.el.PropertyNotFoundException: Property 'actionListener1' not found on type com.example.Bean, потому что binding атрибут по умолчанию интерпретируется как выражение значения, а не как выражение метода. Добавление скобок стиля EL 2.2+ прозрачно превращает выражение значения в выражение метода. См. также.о'. почему я могу привязать к произвольному методу, если он не поддерживается JSF?


действие

использовать action если вы хотите выполнить бизнес действий и при необходимости отрегулировать навигации. Элемент action метод может (таким образом, не должен) возвращать a String который будет использоваться в качестве результата навигационного случая (целевой вид). Возвращаемое значение null или void позволит ему вернуться на ту же страницу и сохранить текущую область просмотра. Возвращаемое значение пустой строки или того же идентификатора представления также возвращается на ту же страницу, но воссоздает область представления и, таким образом, уничтожает все активные бобы области представления и, если применимо, воссоздает их.

The action метод может быть любым допустимым MethodExpression, а также те, которые используют аргументы EL 2.2, такие как ниже:

<h:commandXxx value="submit" action="#{bean.edit(item)}" />

с этим метод:

public void edit(Item item) {
    // ...
}

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

<h:commandLink value="Go to next page" action="#{bean.goToNextpage}" />

с этим бессмысленным методом, возвращающим жестко закодированную строку:

public String goToNextpage() {
    return "nextpage";
}

вместо этого просто поместите эту жестко закодированную строку непосредственно в атрибут:

<h:commandLink value="Go to next page" action="nextpage" />

обратите внимание, что это в свою очередь указывает на плохой дизайн: навигация по почте. Это не пользователь, ни SEO дружественный. Это все объясняется в когда я должен использовать h:outputLink вместо h: commandLink? и должен быть решен как

<h:link value="Go to next page" outcome="nextpage" />

см. также как перемещаться в JSF? Как сделать так, чтобы URL отражал текущую страницу (а не предыдущую).


f: ajax listener

начиная с JSF 2.x есть третий способ,<f:ajax listener>.

<h:commandXxx ...>
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandXxx>

The ajaxListener метод имеет по умолчанию следующие подпись:

import javax.faces.event.AjaxBehaviorEvent;
// ...

public void ajaxListener(AjaxBehaviorEvent event) {
    // ...
}

в Mojarra, в AjaxBehaviorEvent аргумент является необязательным, ниже работает как хорошо.

public void ajaxListener() {
    // ...
}

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

<h:commandXxx ...>
    <f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>

прослушиватели Ajax не очень полезны для компонентов команд. Они более полезны при вводе и выборе компонентов <h:inputXxx>/<h:selectXxx>. В командных компонентах просто придерживайтесь action и/или actionListener для ясности и лучше самодокументированный код. Более того, нравится actionListener на f:ajax listener не поддерживает возврат результата навигации.

<h:commandXxx ... action="#{bean.action}">
    <f:ajax execute="@form" render="@form" />
</h:commandXxx>

для объяснения на execute и render атрибуты, головой к понимание процесса/обновления PrimeFaces и JSF f:ajax execute/render attributes.


вызова ордер

The actionListener s всегда вызываются до the action в том же порядке, как они объявлены в представлении и прикрепленном к компоненту. Элемент f:ajax listener всегда вызывается до любое действие слушателя. Итак, следующий пример:

<h:commandButton value="submit" actionListener="#{bean.actionListener}" action="#{bean.action}">
    <f:actionListener type="com.example.ActionListenerType" />
    <f:actionListener binding="#{bean.actionListenerBinding()}" />
    <f:setPropertyActionListener target="#{bean.property}" value="some" />
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandButton>

вызовет методы в следующем порядке:

  1. Bean#ajaxListener()
  2. Bean#actionListener()
  3. ActionListenerType#processAction()
  4. Bean#actionListenerBinding()
  5. Bean#setProperty()
  6. Bean#action()

обработка исключений

в actionListener поддерживает специальное исключение: AbortProcessingException. Если это исключение выбрасывается из actionListener метод, затем JSF пропустит все оставшиеся прослушиватели действий и метод действия и приступит к непосредственному отображению ответа. Вы не увидите страницу ошибок/исключений, однако JSF будет регистрировать ее. Это также неявно будет сделано всякий раз, когда любое другое исключение выбрасывается из actionListener. Итак, если вы намерены заблокировать страницу по странице ошибки в результате бизнес-исключения, то вы определенно должен выполнять работу в action метод.

Если единственная причина, чтобы использовать actionListener иметь void метод, который возвращает на ту же страницу, то это плохо. Элемент action методы могут прекрасно также возвращать void, напротив того, что некоторые IDE позволяют вам верить через проверку EL. Обратите внимание, что PrimeFaces showcase примеры усеяны такого рода actionListener s по всему месту. Это действительно неправильно. Не используйте это в качестве повод также сделать это самостоятельно.

в ajax-запросах, однако, необходим специальный обработчик исключений. Это независимо от того, используете ли вы на <f:ajax> или нет. Для объяснения и примера, голова к обработка исключений в запросах JSF ajax.

как BalusC указано,actionListener по умолчанию глотает исключения, но в JSF 2.0 есть немного больше к этому. А именно, он не просто глотает и бревна, а на самом деле опубликовывает исключение.

это происходит через вызов такой:

context.getApplication().publishEvent(context, ExceptionQueuedEvent.class,                                                          
    new ExceptionQueuedEventContext(context, exception, source, phaseId)
);

слушатель по умолчанию для этого события является ExceptionHandler который для Mojarra установлен в com.sun.faces.context.ExceptionHandlerImpl. Эта реализация в основном перестроит любое исключение, за исключением тех случаев, когда это касается Исключение AbortProcessingException, которое регистрируется. ActionListeners обернуть исключение, которое генерируется клиентским кодом в таком AbortProcessingException, который объясняет, почему они всегда регистрируются.

этой ExceptionHandler может быть заменен, однако, в faces-config.xml с пользовательской реализацией:

<exception-handlerfactory>
   com.foo.myExceptionHandler
</exception-handlerfactory>

вместо того, чтобы слушать глобально, один боб также может слушать эти события. Следующее является доказательством концепции этого:

@ManagedBean
@RequestScoped
public class MyBean {

    public void actionMethod(ActionEvent event) {

        FacesContext.getCurrentInstance().getApplication().subscribeToEvent(ExceptionQueuedEvent.class, new SystemEventListener() {

        @Override
        public void processEvent(SystemEvent event) throws AbortProcessingException {
            ExceptionQueuedEventContext content = (ExceptionQueuedEventContext)event.getSource();
            throw new RuntimeException(content.getException());
        }

        @Override
        public boolean isListenerForSource(Object source) {
            return true;
        }
        });

        throw new RuntimeException("test");
    }

}

(обратите внимание, это это не так, как обычно следует кодировать слушателей, это только для демонстрационных целей!)

вызывая это из Facelet, как это:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
        <h:form>
            <h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
        </h:form>
    </h:body>
</html>

приведет к отображению страницы с ошибкой.

ActionListener запускается первым, с возможностью изменения ответа, прежде чем действие вызывается и определяет местоположение следующей страницы.

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

вот ссылка, которая описывает отношения:

http://www.java-samples.com/showtutorial.php?tutorialid=605

Comments

    Ничего не найдено.