2013-06-23 24 views
1

我需要记录从托管Bean触发的操作。此链接Logging the invoked managed bean action in a PhaseListener可帮助我解决与操作相关的问题。但是,当我使用actionListener,我有一个NullPointerException在PhaseListener中记录调用的托管bean actionListener

@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; 
} 

NullPointerException与线发生

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

我怎样才能获得actionListener方法的名称? 我试图

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 : `[email protected]` . What I would like to have is `#{bean.action}` .Maybe I did it the wrong way 

回答

2

你是对的好方法,但你需要得到它实现了ActionListenerMethodExpressionActionListener。使用它,你仍然不能从盒子里得到MethodExpression,可能唯一的办法就是通过反思来获得它(不是最好的东西......)。

这就是说,你可以修改你的代码是这样的:

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); 
} 

你会需要这个方法实际上得到了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; 
} 
+0

感谢您的帮助,你的耐心:)与您的帮助解决 – bouikstefan

+0

@bouikstefan不客气,你应该接受它,如果它正确回答你的问题! –