我正在尝试为基于JSF2的应用程序开发更精细的访问日志。我不仅要记录URL访问,还要记录在请求中调用的任何操作,操作方法和侦听器。我首先找到了这个question,它让我开始做得很好。我发现Primefaces有一个小问题,但它很容易纠正。
我现在遇到的问题是f:ajax和p:ajax调用识别侦听器未被记录。
示例:
<f:ajax event="change" listener="#{myBean.onChange()}" />
<p:ajax event="select" listener="#{myBean.onSelect()}" />
我想在我的日志中包含表达式字符串“myBean.doSomething()”。有谁知道如何实现这个目标?
这是我到目前为止所得到的:
public class AccessLogPhaseListener implements PhaseListener {
@Override
public void afterPhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
String action = null;
if (context.isPostback()) {
action = findInvokedCommand(context);
}
// Log...
HttpServletRequest req = (HttpServletRequest) context.getExternalContext().getRequest();
AccessLogUtils.logEntry(req, action);
}
@Override
public void beforePhase(PhaseEvent event) {
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
private String findInvokedCommand(final FacesContext facesContext) {
Map<String, String> params = facesContext.getExternalContext().getRequestParameterMap();
Set<String> clientIds = new HashSet<>();
String behaviorEvent = params.get("javax.faces.behavior.event");
if (facesContext.getPartialViewContext().isAjaxRequest()) {
// This covers <f:ajax> inside UICommand.
clientIds.add(params.get("javax.faces.source"));
} else {
for (Entry<String, String> entry : params.entrySet()) {
// This covers UIForm and UICommand components.
if (entry.getKey().equals(entry.getValue())
// This covers Primefaces p:link and p:commandButton (no value passed)
|| entry.getValue().isEmpty()) {
clientIds.add(entry.getKey());
}
}
}
EnumSet<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED);
final UICommand[] found = new UICommand[1];
facesContext.getViewRoot().visitTree(VisitContext.createVisitContext(facesContext, 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;
}
}
});
if (found[0] != null) {
return found[0].getActionExpression().getExpressionString();
}
return null;
}
}