寫了一個簡單至極的JSF頁面,如下:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
<head>
<title>Hello</title>
</head>
<body>
<f:view>
<h:form>
<h:commandButton actionListener="#{testBean.sayHello}" value="Hello!">
<f:setPropertyActionListener target="#{testBean.userName}"
value="zhangsan" />
<f:actionListener type="myex2.lc.MyActionListener"/>
</h:commandButton>
</h:form>
</f:view>
</body>
</html>
對應(yīng)的Bean如下:
package myex2.lc;
import javax.faces.event.ActionEvent;
public class TestBean {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void sayHello(ActionEvent evt) {
System.out.println("sayWord: Hello, " + userName);
}
}
控制臺上的輸出結(jié)果會是什么呢?答案如下:
sayWord: Hello, null
MyActionListener: Hello, zhangsan
為什么兩個ActionListener(sayHello方法和 <f:actionListener type="myex2.lc.MyActionListener"/>)的輸出會不一樣?
原因在于<f:setPropertyActionListener>也是一個ActionListener,總共3個ActionListener執(zhí)行的順序不同。
正常情況下,attribute中聲明的方法ActionListener,總比<f:actionListener>類的ActionListener先執(zhí)行;
而后<f:actionListener>類的ActionListener再按聲明的先后順序依次執(zhí)行。
所以在這個例子里面執(zhí)行的順序是:#{testBean.sayHello} -> <f:setPropertyActionListener> -> <f:actionListener>。
同時也可看出,對于attribute類的ActionListener,通過<f:setPropertyActionListener>傳遞參數(shù)似乎并不是一個好辦法,還需要構(gòu)建ValueExpression去求值,比較麻煩。
而可以采用<f:attribute>代替,再用ActionEvent的getComponent() -> getAttributes()解析出參數(shù),相對方便一些。
而action屬性總是在各類ActionListener執(zhí)行之后才被調(diào)用,因此沒有此類干擾。
以上情況,也可推及ValueChangeListener。