Ne arasındaki farktır action
ve actionListener
ve ne zaman kullanmalıyım action
karşı actionListener
?
Ne arasındaki farktır action
ve actionListener
ve ne zaman kullanmalıyım action
karşı actionListener
?
Yanıtlar:
Kullanım actionListener
Eğer bir kanca var isterseniz önce gerçek iş eylemin yerine getirilmeyecek, mesela o günlüğe ve / veya (ederek ek özelliği ayarlamak için <f:setPropertyActionListener>
) ve / veya tarafından kullanılabilir eylemi (çağrılan bileşen erişmesini ActionEvent
argüman). Yani, sadece gerçek iş eylemi başlatılmadan önce amaçları hazırlamak için.
actionListener
Yöntem varsayılan aşağıdaki imzası ile vardır:
import javax.faces.event.ActionEvent;
// ...
public void actionListener(ActionEvent event) {
// ...
}
Ve herhangi bir yöntem parantezi olmadan aşağıdaki şekilde ilan edilmesi gerekiyor:
<h:commandXxx ... actionListener="#{bean.actionListener}" />
Eğer geçemez unutmayın ek EL 2.2 ile argümanları. Ancak ActionEvent
özel bağımsız değişken (ler) geçirerek ve belirterek bağımsız değişkeni tamamen geçersiz kılabilirsiniz . Aşağıdaki örnekler geçerlidir:
<h:commandXxx ... actionListener="#{bean.methodWithoutArguments()}" />
<h:commandXxx ... actionListener="#{bean.methodWithOneArgument(arg1)}" />
<h:commandXxx ... actionListener="#{bean.methodWithTwoArguments(arg1, arg2)}" />
public void methodWithoutArguments() {}
public void methodWithOneArgument(Object arg1) {}
public void methodWithTwoArguments(Object arg1, Object arg2) {}
Değişken olmayan yöntem ifadesinde parantezlerin önemine dikkat edin. Eğer olmasaydı, JSF yine de ActionEvent
tartışmalı bir yöntem beklerdi .
EL 2.2+ kullanıyorsanız, birden fazla eylem dinleyici yöntemini aracılığıyla bildirebilirsiniz <f:actionListener binding>
.
<h:commandXxx ... actionListener="#{bean.actionListener1}">
<f:actionListener binding="#{bean.actionListener2()}" />
<f:actionListener binding="#{bean.actionListener3()}" />
</h:commandXxx>
public void actionListener1(ActionEvent event) {}
public void actionListener2() {}
public void actionListener3() {}
Özellikte parantezlerin önemine dikkat edin binding
. Eğer yoklarsa, EL kafa karıştırıcı bir şekilde a atar javax.el.PropertyNotFoundException: Property 'actionListener1' not found on type com.example.Bean
, çünkü binding
öznitelik varsayılan olarak bir yöntem ifadesi olarak değil, bir değer ifadesi olarak yorumlanır. EL 2.2+ stili parantezler şeffaf bir şekilde bir değer ifadesini yöntem ifadesine dönüştürür. Ayrıca bkz. Ao Neden JSF tarafından desteklenmiyorsa <f: actionListener> öğesini rastgele bir yönteme bağlayabiliyorum?
action
Bir iş eylemi yürütmek ve gerekirse gezinmeyi yönetmek istiyorsanız kullanın . action
Yöntemi (ve böylece, gereken olan) bir dönebilir String
navigasyon durumda sonuç (hedef görünümü) olarak kullanılacak olan. null
Veya döndürme değeri void
aynı sayfaya dönmesine izin verir ve geçerli görünüm kapsamını canlı tutar. Boş bir dizenin veya aynı görünüm kimliğinin döndürme değeri de aynı sayfaya dönecek, ancak görünüm kapsamını yeniden oluşturacak ve böylece geçerli olarak etkin görünüm kapsamındaki çekirdekleri yok edecek ve varsa yeniden oluşturacaktır.
action
Yöntem herhangi bir geçerli olabilir MethodExpression
2.2 argümanlar böyle aşağıda EL kullanır, ayrıca olanları:
<h:commandXxx value="submit" action="#{bean.edit(item)}" />
Bu yöntemle:
public void edit(Item item) {
// ...
}
İşlem yönteminiz yalnızca bir dize döndürdüğünde, yalnızca action
öznitelikte tam olarak bu dizeyi belirtebileceğinizi unutmayın . Böylece, bu tamamen sakar:
<h:commandLink value="Go to next page" action="#{bean.goToNextpage}" />
Sabit kodlu bir dize döndüren bu anlamsız yöntemle:
public String goToNextpage() {
return "nextpage";
}
Bunun yerine, bu sabit kodlu dizeyi doğrudan niteliğe koyun:
<h:commandLink value="Go to next page" action="nextpage" />
Bunun sırayla kötü bir tasarımı gösterdiğini lütfen unutmayın: POST ile gezinme. Bu kullanıcı veya SEO dostu değildir. Bu, h: commandLink yerine h: outputLink'i ne zaman kullanmalıyım? ve şu şekilde çözülmesi gerekiyordu:
<h:link value="Go to next page" outcome="nextpage" />
Ayrıca bkz . JSF'de nasıl gezinilir? URL'nin mevcut sayfayı (önceki sayfayı değil) yansıtmasını sağlama .
JSF 2.x beri üçüncü bir yol var <f:ajax listener>
,.
<h:commandXxx ...>
<f:ajax listener="#{bean.ajaxListener}" />
</h:commandXxx>
ajaxListener
Yöntem varsayılan aşağıdaki imzası ile vardır:
import javax.faces.event.AjaxBehaviorEvent;
// ...
public void ajaxListener(AjaxBehaviorEvent event) {
// ...
}
Mojarra'da AjaxBehaviorEvent
argüman isteğe bağlıdır, aşağıda iyi çalışır.
public void ajaxListener() {
// ...
}
Ama MyFaces'de, a MethodNotFoundException
. Argümanı atlamak istediğinizde aşağıdaki her iki JSF uygulamasında da çalışır.
<h:commandXxx ...>
<f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>
Ajax dinleyicileri komut bileşenlerinde gerçekten kullanışlı değildir. Onlar girdi basıp bileşenleri üzerinde daha faydalıdır <h:inputXxx>
/ <h:selectXxx>
. Komut bileşenlerinde, netlik ve daha iyi kendi kendini belgeleyen kod için action
ve / veya bağlı actionListener
kalın. Dahası, böyle actionListener
, f:ajax listener
bir navigasyon sonucu dönen desteklemez.
<h:commandXxx ... action="#{bean.action}">
<f:ajax execute="@form" render="@form" />
</h:commandXxx>
Açıklamalar execute
ve render
öznitelikler için PrimeFaces işlemini / güncellemesini anlama ve JSF f: ajax yürütme / oluşturma özniteliklerine gidin .
actionListener
Hep çağrılan daha önceaction
bu görünümde bildirilen ve bileşen eklenmiş olan aynı sırada. Her f:ajax listener
zaman herhangi bir eylem dinleyicisinden önce çağrılır . Yani, aşağıdaki örnek:
<h:commandButton value="submit" actionListener="#{bean.actionListener}" action="#{bean.action}">
<f:actionListener type="com.example.ActionListenerType" />
<f:actionListener binding="#{bean.actionListenerBinding()}" />
<f:setPropertyActionListener target="#{bean.property}" value="some" />
<f:ajax listener="#{bean.ajaxListener}" />
</h:commandButton>
Yöntemleri aşağıdaki sırayla çağırır:
Bean#ajaxListener()
Bean#actionListener()
ActionListenerType#processAction()
Bean#actionListenerBinding()
Bean#setProperty()
Bean#action()
actionListener
Özel bir istisna destekler: AbortProcessingException
. Bu kural dışı durum bir actionListener
yöntemden atılırsa , JSF kalan eylem dinleyicilerini ve eylem yöntemini atlar ve doğrudan yanıt vermeye devam eder. Bir hata / istisna sayfası görmezsiniz, ancak JSF bunu kaydeder. Bu aynı zamanda bir başka istisna atılırken örtük olarak yapılacaktır actionListener
. Bu nedenle, bir iş istisnası nedeniyle sayfayı bir hata sayfasıyla engellemeyi planlıyorsanız, işi kesinlikle action
yöntemde gerçekleştirmelisiniz.
A kullanmanın tek nedeni aynı sayfaya dönen actionListener
bir void
yönteme sahip olmaksa, bu kötü bir yöntemdir. action
Yöntemler mükemmel da dönebilirsiniz void
bazı IDE EL doğrulama yoluyla inandırmak ne tam tersine,. PrimeFaces vitrin örneklerinin actionListener
her yerde bu tür s ile doldurulduğunu unutmayın . Bu gerçekten yanlış. Bunu kendiniz için bir bahane olarak kullanmayın.
Ancak, ajax isteklerinde özel bir istisna işleyicisi gereklidir. Bu, listener
niteliğini kullanıp kullanmadığınıza bakılmaksızın yapılır <f:ajax>
. Açıklama ve bir örnek için JSF ajax isteklerinde İstisna işleme bölümüne gidin .
actionListener
, ancak bu yine de iş eylemleri için kötüye kullanım actionListener
için iyi bir bahane oluşturmuyor .
action
karşılık gelir. actionListener
ikincil şeyler içindir. Sadece gerektiğinde actionListener
s istisnalarının çoğaltılabileceğini açıklığa kavuşturmak istedim ;)
actionListener
öznitelikte kullanıldığında yöntem adı seçim ücretsizdir ve aynı zamanda olması gerekir public
. Bu processAction
ad yalnızca, yalnızca tam olarak bu yöntem adının tanımlandığı arabirimi <f:actionListener type>
uygulamak zorunda ActionListener
olduğu için kullanılırken processAction
zorunludur.
<f:ajax>
, komut bileşenlerinin action
iş eylemleri için öznitelik kullanmayı tercih edeceğinizi unutmayın . Örn <h:commandButton action="#{bean.businessAction}"><f:ajax/></h:commandButton>
.
BalusC'nin belirttiği gibi, actionListener
varsayılan olarak istisnaları yutar, ancak JSF 2.0'da bunun biraz daha fazlası vardır. Yani, sadece yutar ve günlükleri değil, aynı zamanda istisnayı yayınlar .
Bu, şöyle bir çağrı ile gerçekleşir:
context.getApplication().publishEvent(context, ExceptionQueuedEvent.class,
new ExceptionQueuedEventContext(context, exception, source, phaseId)
);
Bu olay için varsayılan dinleyici ExceptionHandler
Mojarra için ayarlanmış olan dinleyicidir com.sun.faces.context.ExceptionHandlerImpl
. Bu uygulama, günlüğe kaydedilen bir AbortProcessingException özel durumu dışında tüm istisnaları yeniden içerecektir. ActionListeners, istemci kodu tarafından atılan özel durumu, bu tür bir AbortProcessingException içine sararak bunların neden her zaman günlüğe kaydedildiğini açıklar.
Bu ExceptionHandler
özel bir uygulaması ile yüzler-config.xml ancak değiştirilebilir:
<exception-handlerfactory>
com.foo.myExceptionHandler
</exception-handlerfactory>
Küresel olarak dinlemek yerine, tek bir fasulye de bu olayları dinleyebilir. Aşağıdakiler bunun kavramının bir kanıtıdır:
@ManagedBean
@RequestScoped
public class MyBean {
public void actionMethod(ActionEvent event) {
FacesContext.getCurrentInstance().getApplication().subscribeToEvent(ExceptionQueuedEvent.class, new SystemEventListener() {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
ExceptionQueuedEventContext content = (ExceptionQueuedEventContext)event.getSource();
throw new RuntimeException(content.getException());
}
@Override
public boolean isListenerForSource(Object source) {
return true;
}
});
throw new RuntimeException("test");
}
}
(not, normalde dinleyicileri bu şekilde kodlamamalıdır, bu sadece gösterim amaçlıdır!)
Bunu böyle bir Facelet'ten çağırmak:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<h:form>
<h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
</h:form>
</h:body>
</html>
Bir hata sayfasının görüntülenmesine neden olur.
ActionListener, Action çağrılmadan ve sonraki sayfanın konumunu belirlemeden önce, yanıtı değiştirme seçeneği ile önce tetiklenir.
Aynı sayfada aynı yere gitmesi gereken, ancak biraz farklı şeyler yapan birden fazla düğmeniz varsa, her bir düğme için aynı Eylemi kullanabilir, ancak biraz farklı işlevleri işlemek için farklı bir ActionListener kullanabilirsiniz.
İlişkiyi tanımlayan bir link:
TL; DR :
ActionListener
S (birden olabilir) onlar ÖNCE kaydedildi sırayla yürütmekaction
Uzun Cevap :
Bir iş action
tipik bir EJB hizmete neden ve gerekli Ayrıca farklı bir görünüme nihai sonucu ve / veya Navigates'ten ayarlar eğer bir ne yaptığını değilse actionListener
daha uygun yani ne zaman gibi bileşenlerle Kullanıcı etkileşimde, h:commandButton
ya h:link
onlar actionListener
UI Bileşeninin özelliğinde yönetilen fasulye yönteminin adını geçirerek veya bir ActionListener
arabirim uygulayarak ve uygulama sınıfı adını bir UI Bileşeninin özelliğine geçirerek ele alınabilir actionListener
.