我看到的若干mvc框架在展現(xiàn)一個(gè)包含動(dòng)態(tài)數(shù)據(jù)內(nèi)容的頁(yè)面的時(shí)候,都是這樣做的:請(qǐng)求/xx.do,到達(dá)某個(gè)action,執(zhí)行配置好或者根據(jù)url映射到的某個(gè)方法,初始化數(shù)據(jù),放到某個(gè)context里面(例如Request,或者struts用的ognl的context),然后根據(jù)配置或者規(guī)則,forward到某頁(yè)面,然后展現(xiàn)。
這樣做的好處是強(qiáng)制性的分離了展現(xiàn)和邏輯,缺點(diǎn)是多了若干配置,不自然。
JSF的路子和asp/php是一樣的,你請(qǐng)求/a.xhtml,那么,ok,加載/a.xhtml文件。例如a.xhtml主體內(nèi)容如下:
<h:form>
<h:inputText value="#{someAction.txtValue}"/>
<h:commandButton action="#{someAction.saveTxtValue}" value="提交"/>
</h:form>
<h:commandButton action="#{someAction.saveTxtValue}" value="提交"/>
</h:form>
當(dāng)頁(yè)面加載,走到#{someAction.txtValue}這個(gè)表達(dá)式的時(shí)候, 表達(dá)式解析器會(huì)去找spring要一個(gè)名字為someAction的bean。spring發(fā)現(xiàn)自己沒有創(chuàng)建過這樣的一個(gè)bean。根據(jù)bean的定義,于是創(chuàng)建了這樣一個(gè)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現(xiàn)在已經(jīng)被設(shè)置到了this.txtValue上
}
//getters and setters
}
@Scope("request")
public class SomeAction{
private String txtValue;
@PostConstruct
public void init(){
this.txtValue = "the beginning";
}
public void saveTxtValue(){
//do sth.
//用戶輸入的txtValue現(xiàn)在已經(jīng)被設(shè)置到了this.txtValue上
}
//getters and setters
}
這個(gè)類里面的全部?jī)?nèi)容和JSF的技術(shù)細(xì)節(jié)沒有任何關(guān)系,只是一個(gè)簡(jiǎn)單的spring bean。
顯然spring創(chuàng)建這個(gè)bean之后會(huì)調(diào)用標(biāo)注了PostConstruct注解的方法,這里我們做數(shù)據(jù)初始化工作。接下來繼續(xù)頁(yè)面加載過程,于是會(huì)展現(xiàn)出來一個(gè)輸入框,值是the beginning.
這樣做其實(shí)技術(shù)上允許你在頁(yè)面上寫邏輯調(diào)用了,例如直接在頁(yè)面上寫個(gè)#{someAction.xx()},頁(yè)面加載的時(shí)候就會(huì)調(diào)用這個(gè)xx方法,不過根據(jù)實(shí)際項(xiàng)目經(jīng)驗(yàn),大家都能夠保持習(xí)慣,盡量在頁(yè)面上不直接調(diào)用方法完成業(yè)務(wù)邏輯。
你說 “表達(dá)式解析器會(huì)去找spring要一個(gè)名字為someAction的bean”
如果是這樣的話,你spring和jsf集合的時(shí)候,backbean是交給spring幫你管理的。。 不過我看網(wǎng)上看一些jsf和spring的集成。是backbean由jsf自己創(chuàng)建,然后在jsf配置文件加上<application><el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver></application>,讓jsf去尋找spring創(chuàng)建的javabean。。你對(duì)于這種集成有何看法?
另外,在jsf開發(fā)中,一直困擾的問題是,在一個(gè)列表頁(yè)面里使用commandbutton或commandlink會(huì)觸發(fā)jsf的生命周期。當(dāng)點(diǎn)擊的發(fā)送請(qǐng)求的時(shí)候,
在jsf生命周期的RESTORE_VIEW 周期時(shí),會(huì)重復(fù)的查詢列表頁(yè)面使用c:forEach標(biāo)簽的內(nèi)容。。那么如何去避免這個(gè)問題 (前提是:backbean不使用session的情況下,因?yàn)槭褂胹ession線程不安全) 希望能聽聽您的高見。。