JSF get current action in managed bean

2019-05-21 08:36发布

问题:

When user clicks any commandButton, then corresponding action is called in managed bean. Is it possible to get this action name from @PostConstruct method or from event listener method ?

回答1:

The button's name=value pair is by itself available as HTTP request parameter the usual way. Imagine that the generated HTML representation of the command button look like this

<input type="submit" name="formId:buttonId" value="Submit" ... />

Then it's present as a request parameter with name formId:buttonId with a non-null value. JSF uses exactly this information during the Apply Request Values phase to determine if the button was pressed or not. This happens during the decode() method of the renderer associated with the button component, roughly as follows:

if (externalContext.getRequestParameterMap().containsKey(component.getClientId(context))) {
    component.queueEvent(new ActionEvent(component));
}

Or when it concerns an ajax request, then the button's name is instead available as value of the javax.faces.Source request parameter.

if (component.getClientId(context).equals(externalContext.getRequestParameterMap().get("javax.faces.Source"))) {
    component.queueEvent(new ActionEvent(component));
}

Either way, the ActionEvent is ultimately stored as a private field of UIViewRoot which is in no way available by a public API. So, unless you grab reflection and implementation specific hacks, it's end of story here.

To determine the button pressed your best bet is to manually check the request parameter map the same way as JSF itself does.

Depending on the concrete functional requirement, which is not exactly clear from the question, an alternative may be to use actionListener or <f:actionListener> on all UICommand components of interest, or to use <action-listener> in faces-config.xml to register a global one. This will be invoked right before the real action is invoked.



回答2:

UIComponent sourceComponent = UIComponent.getCurrentComponent(FacesContext.getCurrentInstance());