ajax isteği için aslında ne log olduğunu. Yöntemin adı (Bu çağrıda örneğin "findAddress": <p:ajax process="contactDetails" update="@form" listener="#{aboutYouController.findAddress}" ....
) ajax tarafından çağrılan Mesela
Bu bilgiler JSF bileşen ağacında kullanılabilir. JSF bileşen ağacı yalnızca görünüm oluşturma süresinden sonra kullanılabilir. Bir görünüm yalnızca istek FacesServlet
tarafından sunulduğunda oluşturulur. Böylece, bir sunucu filtresi, herhangi bir sunucu uygulamasından önce çalıştığı kadar erken. Bir postback görünüm aşamasını geri yükledikten sonra
Sen en iyisi kodu kaçardım. JSF bileşen ağacının o anda kullanılabilir olduğu garanti edilir. Mevcut isteğin bir geri gönderme olup olmadığını kontrol etmek için FacesContext#isPostback()
'u kullanabilirsiniz. Mevcut isteğin bir ajax isteği olup olmadığını kontrol etmek için PartialViewContext#isAjaxRequest()
'u kullanabilirsiniz. Ajax isteğinin kaynak bileşeninin istemci kimliğini almak için önceden tanımlanmış javax.faces.source
istek parametresini kullanabilirsiniz. Sen ajax Etkinlik adı (örneğin change
, click
, action
, vs) elde etmek için önceden tanımlanmış javax.faces.behavior.event
istek parametresini kullanabilirsiniz. ilişkilendirilmiş davranışın dinleyicileri elde
bir öykü dışında sırayla olduğunu. Bu, MethodExpression
yalnızca ActionSource2#getActionExpression()
tarafından kullanılabilir olduğundan ActionSource2
bileşenlerinde (ör. <h|p:commandButton action="#{...}">
) kolaydır. Ancak, bu API'nin getBehaviorListeners()
gibi bir yöntemi olmadığı için bu BehaviorBase
etiketleyicilerinde (ör. <f|p:ajax listener="#{...}">
) kolay değildir. Bunları eklemek ve kaldırmak için yalnızca bir yöntem vardır, ancak bunların bir listesini elde etmek için değil. Yani bazı kötü yansıma hilesi, adı JSF uygulaması özel olan dinleyicilerle private
alanına erişmek için gereklidir. Mojarra'da, listeners
ve MyFaces'de _behaviorListeners
. Her ikisi de List
'dan atanabilir ve bu türün tek alanıdır, bu yüzden bunu kontrol edebiliriz. Bir kez o zaman hala o örneğinin MethodExpression
alanını elde etmek için başka bir yansıma hile yapmak gerekir, BehaviorListener
örneğinin ele sahip. Yuck.
Sonuçta, burada hile afterPhase
RESTORE_VIEW
ait dinleyen bir PhaseListener
lezzet nasıl göründüğünü nasıl:
o koşmak
faces-config.xml
gibi, altta kayıt alabilmek için
public class AjaxActionLoggerPhaseListener implements PhaseListener {
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
@Override
public void beforePhase(PhaseEvent event) {
// NOOP.
}
@Override
public void afterPhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
if (!(context.isPostback() && context.getPartialViewContext().isAjaxRequest())) {
return; // Not an ajax postback.
}
Map<String, String> params = context.getExternalContext().getRequestParameterMap();
String sourceClientId = params.get("javax.faces.source");
String behaviorEvent = params.get("javax.faces.behavior.event");
UIComponent source = context.getViewRoot().findComponent(sourceClientId);
List<String> methodExpressions = new ArrayList<>();
if (source instanceof ClientBehaviorHolder && behaviorEvent != null) {
for (ClientBehavior behavior : ((ClientBehaviorHolder) source).getClientBehaviors().get(behaviorEvent)) {
List<BehaviorListener> listeners = getField(BehaviorBase.class, List.class, behavior);
if (listeners != null) {
for (BehaviorListener listener : listeners) {
MethodExpression methodExpression = getField(listener.getClass(), MethodExpression.class, listener);
if (methodExpression != null) {
methodExpressions.add(methodExpression.getExpressionString());
}
}
}
}
}
if (source instanceof ActionSource2) {
MethodExpression methodExpression = ((ActionSource2) source).getActionExpression();
if (methodExpression != null) {
methodExpressions.add(methodExpression.getExpressionString());
}
}
System.out.println(methodExpressions); // Do your thing with it.
}
private static <C, F> F getField(Class<? extends C> classType, Class<F> fieldType, C instance) {
try {
for (Field field : classType.getDeclaredFields()) {
if (field.getType().isAssignableFrom(fieldType)) {
field.setAccessible(true);
return (F) field.get(instance);
}
}
} catch (Exception e) {
// Handle?
}
return null;
}
}
:
<lifecycle>
<phase-listener>com.example.AjaxActionLoggerPhaseListener</phase-listener>
</lifecycle>
Yukarıda, Mojarra ve PrimeFaces ile test edilmiş ve uyumludur ve teorik olarak MyFaces ile uyumludur.
Güncelleme: durumda almak için Components#getActionExpressionsAndListeners()
MTU yarar kütüphanesini OmniFaces kullanarak veya açık, yeni Components#getCurrentActionSource()
yarar yöntemini kullanabilirsiniz sürüm 2.4 beri mevcut eylem kaynak bileşeni bulmak için ve konum Belirli bir bileşene kayıtlı tüm eylem yöntemlerinin ve dinleyicilerin listesi. Bu, normal (ajax olmayan) isteklerde de kullanılabilir. Bunun üzerine, yukarıdaki PhaseListener
örnek olarak aşağıda azaltılabilir:
public class FacesActionLoggerPhaseListener implements PhaseListener {
@Override
public PhaseId getPhaseId() {
return PhaseId.PROCESS_VALIDATIONS;
}
@Override
public void beforePhase(PhaseEvent event) {
// NOOP.
}
@Override
public void afterPhase(PhaseEvent event) {
if (!event.getFacesContext().isPostback())) {
return;
}
UIComponent source = Components.getCurrentActionSource();
List<String> methodExpressions = Components.getActionExpressionsAndListeners(source);
System.out.println(methodExpressions); // Do your thing with it.
}
}
özellikle dinleyici yöntemi adı, masal lütfen buraya bir göz hakkında: http://stackoverflow.com/questions/11860550/jsf-get-current -işlemde yönetilen-fasulye –
@tt_dev İlginç. Bunu potansiyel olarak kullanabilirim, ancak faceContext benim filtremde fasulye olmadığı için mevcut değildir. Ben faceContext standart istek/oturum içinde bir yerden tutulabilir inanıyorum, ama nerede hatırlamıyorum. Uygulamamı hata ayıklamada kullanıyorum. –
Bu sorunun indirilmesinin bir nedeni yok. – Tiny