h:commandButtonのactionListenerでactionを実施するか否かを指定する方法

#目的
actionListenerにて特定の条件を満たす場合、action・又は後続のactionListenerを実行させたくない。
だけど、RenderResponsePhaseの処理は実行させたい・renderや、ajaxのcomplete/successの処理を実行させたいというのが目的です。
※h:commandButton以外、でも使えるほうほうです

#実装方法
まっとうな方法はなさそうでしたので、以下の方法で実現しました。

1.例外クラスを作成
2.フェーズリスナーを作成（InvokeApplicationPhase）
　※afterPhaseで1.で作成した例外クラスがあったらつぶす
3.faces-config.xmlにフェーズリスナーを登録


1.例外クラスを作成

```BusinessException.java
public class BusinessException extends RuntimeException {
	private static final long serialVersionUID = 1L;
}
```
2.フェーズリスナーを作成（InvokeApplicationPhase）

```InvokeApplicationPhaseListener.java
package action;

import java.util.Iterator;

import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

public class InvokeApplicationPhaseListener implements PhaseListener {
	private static final long serialVersionUID = 1L;
	@Override
	public void afterPhase(PhaseEvent event) {
		FacesContext context = event.getFacesContext();
		Iterator<ExceptionQueuedEvent> ite = context.getExceptionHandler().getUnhandledExceptionQueuedEvents().iterator();
		while (ite.hasNext()) {
			ExceptionQueuedEvent e = ite.next();
			Throwable t = e.getContext().getException();
			do {
				if (t instanceof BusinessException) {
					ite.remove();
					break;
				}
				t = t.getCause();
			} while (t != null);
		}
	}
	@Override
	public void beforePhase(PhaseEvent event) {
	}
	@Override
	public PhaseId getPhaseId() {
		return PhaseId.INVOKE_APPLICATION;
	}
}
```
3.faces-config.xmlにフェーズリスナーを登録

```faces-config.xml
<?xml version="1.0"?>
<faces-config version="2.3"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd">
    <lifecycle>
        <phase-listener>action.InvokeApplicationPhaseListener</phase-listener>
    </lifecycle>
</faces-config>

```
#確認

actionListener内で、上記で作成した例外クラスをスロー
　※これでInvokeApplicationPhase内の処理を中断できる

```ActionStopTest.xhtml

<h:commandButton value="test"
				actionListener="#{actionTestListener.method1()}"
				action="#{actionTestListener.method4()}">
	<f:actionListener binding="#{actionTestListener.method2()}"/>
	<f:actionListener binding="#{actionTestListener.method3()}"/>
	<f:ajax onevent="function(data) {console.log(data.status);}"></f:ajax>
</h:commandButton>
```

```ActionTestListener.java
@RequestScoped
@Named
public class ActionTestListener {
	public void method1() {
		System.out.println("method1");
	}
	public void method2() {
		System.out.println("method2");
		throw new BusinessException();
	}
	public void method3() {
		System.out.println("method3");
	}
	public void method4() {
		System.out.println("method4");
	}
}
```
#結果

スタックトレースが表示されてしまうのはうまく防ぐ方法が見つけられませんでした。
が、method2での例外発生以降、処理が止まっています。

```
08:55:03,896 INFO  [stdout] (default task-1) method1

08:55:03,896 INFO  [stdout] (default task-1) method2

08:55:03,896 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (default task-1) /ActionStopTest.xhtml @19,67 binding="#{actionTestListener.method2()}": action.BusinessException: javax.el.ELException: /ActionStopTest.xhtml @19,67 binding="#{actionTestListener.method2()}": action.BusinessException
	at com.sun.jsf-impl@2.3.9.SP03//com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:77)
	at com.sun.jsf-impl@2.3.9.SP03//com.sun.faces.facelets.tag.jsf.core.ActionListenerHandler$LazyActionListener.processAction(ActionListenerHandler.java:68)
	at javax.faces.api@3.0.0.Final//javax.faces.event.ActionEvent.processListener(ActionEvent.java:72)
	at javax.faces.api@3.0.0.Final//javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:490)
	at javax.faces.api@3.0.0.Final//javax.faces.component.UICommand.broadcast(UICommand.java:211)
	at javax.faces.api@3.0.0.Final//javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:847)
	at javax.faces.api@3.0.0.Final//javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1395)
	at com.sun.jsf-impl@2.3.9.SP03//com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:58)
	at com.sun.jsf-impl@2.3.9.SP03//com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
	at com.sun.jsf-impl@2.3.9.SP03//com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:177)
	at javax.faces.api@3.0.0.Final//javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:707)
	at javax.faces.api@3.0.0.Final//javax.faces.webapp.FacesServlet.service(FacesServlet.java:451)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at io.opentracing.contrib.opentracing-jaxrs2//io.opentracing.contrib.jaxrs2.server.SpanFinishingFilter.doFilter(SpanFinishingFilter.java:52)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
	at io.undertow.core@2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.core@2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.core@2.0.26.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
	at io.undertow.core@2.0.26.Final//io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.core@2.0.26.Final//io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.core@2.0.26.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.core@2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
	at io.undertow.core@2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
	at io.undertow.core@2.0.26.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
	at org.wildfly.extension.undertow@18.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
	at io.undertow.core@2.0.26.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)
	at io.undertow.core@2.0.26.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
	at org.jboss.threads@2.3.3.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
	at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
	at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.el.ELException: action.BusinessException
	at javax.el.api@2.0.0.Final//javax.el.ELUtil.invokeMethod(ELUtil.java:251)
	at javax.el.api@2.0.0.Final//javax.el.BeanELResolver.invoke(BeanELResolver.java:338)
	at javax.el.api@2.0.0.Final//javax.el.CompositeELResolver.invoke(CompositeELResolver.java:198)
	at org.glassfish.jakarta.el@3.0.2//com.sun.el.parser.AstValue.getValue(AstValue.java:111)
	at org.glassfish.jakarta.el@3.0.2//com.sun.el.parser.AstValue.getValue(AstValue.java:179)
	at org.glassfish.jakarta.el@3.0.2//com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:202)
	at org.jboss.weld.core@3.1.2.Final//org.jboss.weld.module.web.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
	at org.jboss.weld.core@3.1.2.Final//org.jboss.weld.module.web.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
	at com.sun.jsf-impl@2.3.9.SP03//com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:73)
	... 59 more
Caused by: action.BusinessException
	at deployment.test.war//action.ActionTestListener.method2(ActionTestListener.java:14)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at javax.el.api@2.0.0.Final//javax.el.ELUtil.invokeMethod(ELUtil.java:245)
	... 67 more
```
f:ajaxのoneventで指定した処理はちゃんと実施されているのがわかります。

```ブラウザ
begin
complete
success
```