我看到的若干mvc框架在展現一個包含動態數據內容的頁面的時候,都是這樣做的:請求/xx.do,到達某個action,執行配置好或者根據url映射到的某個方法,初始化數據,放到某個context里面(例如Request,或者struts用的ognl的context),然后根據配置或者規則,forward到某頁面,然后展現。
這樣做的好處是強制性的分離了展現和邏輯,缺點是多了若干配置,不自然。
JSF的路子和asp/php是一樣的,你請求/a.xhtml,那么,ok,加載/a.xhtml文件。例如a.xhtml主體內容如下:
<h:form>
<h:inputText value="#{someAction.txtValue}"/>
<h:commandButton action="#{someAction.saveTxtValue}" value="提交"/>
</h:form>
當頁面加載,走到#{someAction.txtValue}這個表達式的時候, 表達式解析器會去找spring要一個名字為someAction的bean。spring發現自己沒有創建過這樣的一個bean。根據bean的定義,于是創建了這樣一個bean。該類定義如下:
@Component("someAction")
@Scope("request")
public class SomeAction{
private String txtValue;
@PostConstruct
public void init(){
this.txtValue = "the beginning";
}
public void saveTxtValue(){
//do sth.
//用戶輸入的txtValue現在已經被設置到了this.txtValue上
}
//getters and setters
}
這個類里面的全部內容和JSF的技術細節沒有任何關系,只是一個簡單的spring bean。
顯然spring創建這個bean之后會調用標注了PostConstruct注解的方法,這里我們做數據初始化工作。接下來繼續頁面加載過程,于是會展現出來一個輸入框,值是the beginning.
這樣做其實技術上允許你在頁面上寫邏輯調用了,例如直接在頁面上寫個#{someAction.xx()},頁面加載的時候就會調用這個xx方法,不過根據實際項目經驗,大家都能夠保持習慣,盡量在頁面上不直接調用方法完成業務邏輯。