繁体   English   中英

如何记录在servlet过滤器中调用的托管bean名称和操作方法

[英]How to log managed bean name and action method being invoked in a servlet filter

我正在开发一个基于JSF 2 Mojarra构建的Web应用程序。 我需要通过我的servlet过滤器记录一些检测信息。 为此,我还需要知道调用哪个ManagedBean和哪个方法。

有没有办法获得这些信息? 我无法访问FacesContext因为在请求到达Faces Servlet之前调用了过滤器。

我收集到您要记录被调用的UICommand组件。 servlet过滤器是不可或缺的,因为它无法访问FacesContext ,更不用说最终需要遍历的UIViewRoot FacesContext (以及本质上也是UIViewRoot ,et.al)是由FacesServlet创建的,它是一个不错的servlet,完全符合所有过滤器调用的servlet规范 因此,无法在servlet过滤器中获取FacesContext 确实,有一些方法可以创建自己的FacesContext实例,但如果存在满足要求的“正确方法”,则绝对不建议这样做。

您应该使用正确的工具来完成工作,在这种情况下,这是一个阶段监听器。 以下是相位监听器的外观和应该如何注册的启动示例:

public class MyPhaseListener implements PhaseListener {

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        // Do your job here which should run right before the RESTORE_VIEW phase.
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        // Do your job here which should run right after the RESTORE_VIEW phase.
    }

}

要使其运行,请在faces-config.xml中将其注册如下:

<lifecycle>
    <phase-listener>com.example.MyPhaseListener</phase-listener>
</lifecycle>

您可以将getPhaseId()结果更改为您的洞察力,例如PhaseId.RENDER_RESPONSE ,然后阶段侦听器将在渲染响应阶段之前和之后启动。

这是一个具体的启动示例,它可以完成您正在寻找的工作(查找正在调用的命令组件并记录其操作方法表达式):

public class InvokedCommandComponentLogger implements PhaseListener {

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        // NOOP. The view hasn't been restored yet at that point, so the component tree wouldn't be available anyway.
    }

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

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

            if (component != null) {
                String methodExpression = component.getActionExpression().getExpressionString();
                System.out.println("Method expression of the action being invoked: " + methodExpression);
            }
        }
    }

    private UICommand findInvokedCommandComponent(FacesContext context) {
        Map<String, String> params = context.getExternalContext().getRequestParameterMap();
        Set<String> clientIds = new HashSet<>();

        if (context.getPartialViewContext().isAjaxRequest()) {
            clientIds.add(params.get("javax.faces.source")); // This covers <f:ajax> inside UICommand.
        } else {
            for (Entry<String, String> entry : params.entrySet()) {
                if (entry.getKey().equals(entry.getValue())) { // This covers UIForm and UICommand components.
                    clientIds.add(entry.getKey());
                }
            }
        }

        EnumSet<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED);
        final UICommand[] found = new UICommand[1];
        context.getViewRoot().visitTree(VisitContext.createVisitContext(context, clientIds, hints), new VisitCallback() {
            @Override
            public VisitResult visit(VisitContext context, UIComponent target) {
                if (target instanceof UICommand) {
                    found[0] = (UICommand) target;
                    return VisitResult.COMPLETE;
                } else {
                    return VisitResult.ACCEPT;
                }
            }
        });

        return found[0];
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM