Question

I need to log actions fired from managed Bean.This link , Logging the invoked managed bean action in a PhaseListener helps me solve the problem related to actions. But, when I use actionListener , I have a NullPointerException

@Override
public void beforePhase(PhaseEvent event) {
    FacesContext context = event.getFacesContext();

    if (context.isPostback()) {
        UICommand component = findInvokedCommandComponent(context);

        if (component != null) {
            String methodExpression = component.getActionExpression().getExpressionString(); 
            // It'll contain #{bean.action}.
        }
    }
}

private UICommand findInvokedCommandComponent(FacesContext context) {
    UIViewRoot view = context.getViewRoot();
    Map<String, String> params = context.getExternalContext().getRequestParameterMap();

    if (context.getPartialViewContext().isAjaxRequest()) {
        return (UICommand) view.findComponent(params.get("javax.faces.source"));
    } else {
        for (String clientId : params.keySet()) {
            UIComponent component = view.findComponent(clientId);

            if (component instanceof UICommand) {
                return (UICommand) component;
            }
        }
    }

    return null;
}

THe NullPointerException occurs with line

String methodExpression = component.getActionExpression().getExpressionString(); 

How can I get the name of the actionListener method ? I tried

private UICommand findInvokedCommandComponent(FacesContext context) {
        UIViewRoot view = context.getViewRoot();
        Map<String, String> params = context.getExternalContext().getRequestParameterMap();

        if (context.getPartialViewContext().isAjaxRequest()) {
            UIComponent component = view.findComponent(params.get("javax.faces.source"));
            if (component instanceof UICommand) {
//                component.get
              UICommand comp=  (UICommand) component;
                ActionListener[] actionListeners=  comp.getActionListeners();
                System.out.println("Taille des Listeners : "+actionListeners.length);
               ActionListener method;
                method = actionListeners[0];
                String toString = method.toString();
                System.out.println("ActionListener : "+toString);
                return (UICommand) component;
            }
        } else {
            for (String clientId : params.keySet()) {
                UIComponent component = view.findComponent(clientId);

                if (component instanceof UICommand) {
                    return (UICommand) component;
                }
            }
        }

        return null;
    }
System.out.println("ActionListener : "+toString); returns ActionListener : `javax.faces.event.MethodExpressionActionListener@16a779b` . What I would like to have is  `#{bean.action}` .Maybe I did it the wrong way
Was it helpful?

Solution

You were on the good way, but you need to get the MethodExpressionActionListener which implements the ActionListener. Using it, you still can't get the MethodExpression out of the box, probably the only way is to get it by reflection (not the best thing...).

That said, you can modify your code like this :

if (component != null) {
    String methodExpression = "";

    if(component.getActionExpression() != null)
    {
        methodExpression = component.getActionExpression().getExpressionString(); 
    }
    else if(component.getActionListeners().length > 0)
    {
        methodExpression = getActionListener((MethodExpressionActionListener)component.getActionListeners()[0]).getExpressionString();
    }

    System.out.println("Method Expression : " + methodExpression);
}

And you will need this method to actually get required information out of the MethodExpressionActionListener :

private MethodExpression getActionListener(MethodExpressionActionListener listener)
{
    MethodExpression expression = null;
    Field field;

    try
    {
        field = listener.getClass().getDeclaredField("methodExpressionZeroArg");
        field.setAccessible(true);
        expression = (MethodExpression)field.get(listener);

        if(expression == null)
        {
            field = listener.getClass().getDeclaredField("methodExpressionOneArg");
            field.setAccessible(true);
            expression = (MethodExpression)field.get(listener);
        }
    }
    catch(Exception e)
    {

    }

    return expression;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top