commandLink问题

wula0010 2008-12-17
adminStudentList.jsp页面:
<%@page contentType="text/html"%>
......
<body>
        <f:view>
            <h:form id="pageforstuCheck">
                <h:panelGroup>
                    <h:panelGrid>
                        <h:outputText value="学生检索" />
                    </h:panelGrid>
                    <h:panelGrid columns="5" cellpadding="0" styleClass="styleClazz"
                                 headerClass="headerClazz" footerClass="footerClazz"
                                 rowClasses="row1" columnClasses="column1">
                        <h:outputText value="选择班级:" />
                        <h:selectOneMenu value="#{StudentBean.classname}">
                            <f:selectItem itemValue="0" itemLabel="全部" />
                            <f:selectItems value="#{StudentBean.languageMap}" />
                        </h:selectOneMenu>
                        <h:outputText value="请输入姓名" />
                        <h:inputText value="#{StudentBean.name}" />
                        <h:commandLink actionListener="#{StudentBean.searchByName}">
                            <h:outputText value="查找" />
                        </h:commandLink>
                    </h:panelGrid>
                </h:panelGroup>
            </h:form>
            <h:form id="form1">
                <h:dataTable id="stuListPage" value="#{StudentBean.stuList}" var="stu" styleClass="table" headerClass="tableHeader"
                             columnClasses="oddColumn,evenColumn" width="600px" rendered="true">
                    <h:column>
                        <f:facet name="header"><h:outputText value="学号"/></f:facet>
                        <h:outputText value="#{stu.id}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><h:outputText value="姓名"/></f:facet>
                        <h:outputText value="#{stu.name}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"><h:outputText value="修改"/></f:facet>
                        <h:commandLink actionListener="#{StudentBean.update}" action="success"><h:outputText value="修改"/>
                            <f:param id="uid" name="uid" value="#{stu.id}"/>
                        </h:commandLink>
                    </h:column>                   
                </h:dataTable>
            </h:form>
        </f:view>
    </body>
</html>

java文件:
public class StudentBean {
    private String classname;
    private static Map languageMap=null;
    private String name="";
    public StudentDAO studentDAO;
    private List stuList=new ArrayList();
    public StudentService studentService=new StudentService();

    /** Creates a new instance of StudentBean */
    public StudentBean() {
        stuList = studentService.getAllStudent();
    }
......
    public void searchByName(ActionEvent event){
        int cid=1;
        if(classname!=null){
            cid = Integer.parseInt(classname);
        }
        stuList=new ArrayList();
        stuList =studentService.getStudentByName(cid, name);
    }
......
    public void update(ActionEvent event){
        String ss="hello";
    }
}

faces-config里:
<navigation-rule>
    <from-view-id>/manage.jsp</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/updateStudent.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

程序运行,点击
<f:facet name="header"><h:outputText value="修改"/></f:facet>
    <h:commandLink actionListener="#{StudentBean.update}" action="success"><h:outputText value="修改"/>
       <f:param id="uid" name="uid" value="#{stu.id}"/>
    </h:commandLink>
会先执行StudentBean.update,然后跳转到updateStudent.jsp,并把当前行的stu.id传递过去。

问题:
public StudentBean() {
   stuList = StudentService.getAllStudent();
}
这个是StudentBean的构造函数,在这里取所有学生的信息显示,这样的话,当执行页面所有的事件的时候,都要执行StudentBean()的构造函数,如果我的数据很多,有几万甚至上百万的时候,这样非常浪费时间,于是我想,也没有必要在这里选择所有学生列表,就把stuList = StudentService.getAllStudent();这句去掉了,逻辑上应该没有问题,但是,运行的时候,就不对了:
点击
<f:facet name="header"><h:outputText value="修改"/></f:facet>
    <h:commandLink actionListener="#{StudentBean.update}" action="success"><h:outputText value="修改"/>
        <f:param id="uid" name="uid" value="#{stu.id}"/>
    </h:commandLink>
点击这个按钮联接的时候,就不执行StudentBean.update这个了,也不执行action="success"跳转到下个页面了,直接返回adminStudentList.jsp,学生列表就空了。

我不明白为什么会这样,根据jsf程序执行生命周期的流程,应该如下:
1、回复画面(Restore View)
2、套用申请值(Apply Request Values)
3、执行验证(Process Validations)
4、更新模型值(Update Model Values)
5、唤起应用程序(Invoke Application)
6、绘制回应(Render Response)

我写了个ShowPhaseListener.java来跟踪程序流程,发现是在“套用申请值(Apply Request Values)”阶段执行构造函数的,这个我就不明白了,为什么会这样?

套用申请值(Apply Request Values):每个组件尝试从到来的请求中找寻自己的参数并更新组件值,在这边会触发ActionEvent,这个事件会被排入队列中,然后在唤起应用程序阶段之后才会真正由事件处理者进行处理。
然而对于设定immeduate为true的命令(Commamnd)组件来说,会立即处理事件并跳过之后的阶段直接绘制响应,而对于设定immediate为true的输入(Input)组件,会马上进行转换验证并处理值变事件,之后跳过接下来的阶段,直接绘制响应。
这个不是应该从组件树里取值么?
就算不是,我的构造函数是空的,也不应该影响程序的流程啊............

请大家指教指教。
wula0010 2008-12-17
我做了个测试,
public StudentBean() {
   stuList = StudentService.getAllStudent();
}
这个,改成:
public StudentBean() {
int cid = 1;
stuList=new ArrayList();
stuList = StudentService.findStudentByStudentName(cid, name);
}

这样,初始页面有3条记录(小学的),然后再查询所有学生,再点击
<f:facet name="header"><h:outputText value="修改"/></f:facet>
    <h:commandLink actionListener="#{StudentBean.update}" action="success"><h:outputText value="修改"/>
        <f:param id="uid" name="uid" value="#{stu.id}"/>
    </h:commandLink>

这样,前3条记录,都可以正确执行,后面的记录就不能正确执行,这说明构造函数里stuList的记录数影响了后面的取值执行,是不是jsf的bug?......
rockjava 2008-12-17
引用
我不明白为什么会这样,根据jsf程序执行生命周期的流程,应该如下:
1、回复画面(Restore View)
2、套用申请值(Apply Request Values)
3、执行验证(Process Validations)
4、更新模型值(Update Model Values)
5、唤起应用程序(Invoke Application)
6、绘制回应(Render Response)

这几个阶段的术语是谁翻译的?
terryzhou 2008-12-17
在<h:commandLink/>里加个immediate="true"试试?

wula0010 2008-12-18
rockjava 写道
引用
我不明白为什么会这样,根据jsf程序执行生命周期的流程,应该如下:
1、回复画面(Restore View)
2、套用申请值(Apply Request Values)
3、执行验证(Process Validations)
4、更新模型值(Update Model Values)
5、唤起应用程序(Invoke Application)
6、绘制回应(Render Response)

这几个阶段的术语是谁翻译的?



很多书上都是这么讲的,有问题?
wula0010 2008-12-18
terryzhou 写道
在<h:commandLink/>里加个immediate="true"试试?



结果一样,这个参数是通过<f:param id="uid" name="uid" value="#{stu.id}"/>来传递的,和immediate没关系吧
wula0010 2008-12-18
哈哈,想了一个变通的办法,其实我只是想把表里的参数传递到另外一个页面,不用<h:commandLink>,用<h:outputLink>:
<h:column>
    <f:facet name="header"><h:outputText value="修改1"/></f:facet>
    <h:outputLink value="updateStudent.faces?uid=#{stu.id}"><h:outputText value="修改"/></h:outputLink>
</h:column>

这样,在页面生成的代码为:<a href="updateStudent.faces?uid=6">修改</a>,运行时,程序直接跳转到updateStudent.faces页面,不经过StudentBean的构造函数了。测试ok!
terryzhou 2008-12-19
wula0010 写道
哈哈,想了一个变通的办法,其实我只是想把表里的参数传递到另外一个页面,不用<h:commandLink>,用<h:outputLink>:
<h:column>
    <f:facet name="header"><h:outputText value="修改1"/></f:facet>
    <h:outputLink value="updateStudent.faces?uid=#{stu.id}"><h:outputText value="修改"/></h:outputLink>
</h:column>

这样,在页面生成的代码为:<a href="updateStudent.faces?uid=6">修改</a>,运行时,程序直接跳转到updateStudent.faces页面,不经过StudentBean的构造函数了。测试ok!



你到底用了几个BEAN?汗
updateStudent
StudentBean

这跟你参数怎么传法一点关系没有。。。

wula0010 2008-12-19
terryzhou 写道


你到底用了几个BEAN?汗
updateStudent
StudentBean

这跟你参数怎么传法一点关系没有。。。



两个页面,两个bean,怎么了呢?几个bean有什么关系,一个页面多个bean也没说不可以啊,............
wula0010 2008-12-19
terryzhou 写道


你到底用了几个BEAN?汗
updateStudent
StudentBean

这跟你参数怎么传法一点关系没有。。。



updateStudent.faces是另外一个页面,这个页面和几个bean有什么关系
Global site tag (gtag.js) - Google Analytics