2012-09-10 25 views
1

我有非常简单的JSF 2.0应用程序(见下文)。问题是当存在ui:repeat时,执行顺序(我在调试器中使用断点检查它)很奇怪。<ui:repeat> JSF 2.0中断方法执行顺序

在我提交表格之后,SecondBean.initSomething()被称为FirstBean.setFirstFormField()之前。如果我将something的类型更改为String,并从index.jsf中删除ui:repeat并仅使用h:outputText,则所有内容均按预期工作,FirstBean.setFirstFormField()SecondBean.initSomething()之前调用。

我在做什么错了?我正在使用JDeveloper Studio Edition 11.1.2.2.0及其堆栈(WebLogic 10.3.5.0,Java 6和JSF 2.0)。

下面的代码:

index.jsf:

<?xml version='1.0' encoding='UTF-8'?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
     <h:head></h:head> 
     <h:body> 
      <h:form> 
       <h:panelGrid columns="1"> 
        <h:inputText value="#{firstBean.firstFormField}" /> 
        <h:commandButton action="#{firstBean.processForm}" value="Submit" /> 
       </h:panelGrid> 
      </h:form> 
      <ui:repeat value="#{secondBean.something}" var="variable" > 
       <h:outputText value="#{variable}" /> 
      </ui:repeat> 
     </h:body> 
    </html> 
</f:view> 

FirstBean.java:

package test.backing; 

import javax.faces.bean.*; 
import javax.faces.context.FacesContext; 

@ManagedBean 
@RequestScoped 
public class FirstBean { 
    private String firstFormField; 
    public FirstBean() { 
     super(); 
    } 

    public String processForm() { 
     FacesContext facesContext; 

     facesContext = FacesContext.getCurrentInstance(); 

     return facesContext.getViewRoot().getViewId();    
    } 

    public void setFirstFormField(String firstFormField) { 
     this.firstFormField = firstFormField; 
    } 

    public String getFirstFormField() { 
     return this.firstFormField; 
    } 
} 

SecondBean.java:

package test.backing; 

import java.util.*; 

import javax.annotation.PostConstruct; 

import javax.faces.bean.*; 

@ManagedBean 
@RequestScoped 
public class SecondBean { 
    private List<String> something; 

    public SecondBean() { 

    } 

    @PostConstruct 
    public void initSomething() { 
     this.something = Arrays.asList("abc", "cde"); 
    } 

    public void setSomething(List<String> something) { 
     this.something = something; 
    } 

    public List<String> getSomething() { 
     return this.something; 
    } 
} 

faces-config.xml中:

<?xml version="1.0" encoding="UTF-8"?> 
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"> 

</faces-config> 

的web.xml:

<?xml version = '1.0' encoding = 'UTF-8'?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
     version="2.5"> 
    <context-param> 
    <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name> 
    <param-value>*.jsf;*.xhtml</param-value> 
    </context-param> 
    <servlet> 
    <servlet-name>Faces Servlet</servlet-name> 
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>Faces Servlet</servlet-name> 
    <url-pattern>/faces/*</url-pattern> 
    </servlet-mapping> 
</web-app> 
+0

我的猜测是,'UI:repeat',是Facelets的部分(我猜测不是一个“真正的”JSF组件),它是在处理的早期阶段而不是“h:inputText”或“h:outputText”中评估的。 (恢复视图与应用请求值或更新模型值。)虽然我已经接触JSF已经有一段时间了。 – millimoose

回答

1

我做错了吗?

没有。它按照规定工作。它只是在恢复视图时调用。

如果这对您造成了一个特定的问题,遗憾的是根本没有在问题中详细描述,那么需要寻找一个解决方案,而不是依赖于/依赖于bean构建的某个特定执行顺序或相对于视图的getter调用。至少,这是你似乎出于某种原因所针对的目标。


无关的具体问题,在processForm()操作方法你也可以只返回null导航回到当前视图。这比目前的笨拙方法简单得多。

0

这就是JSF循环的工作原理。该命令是正确的...

你需要改变你正在做的同意JSF框架的规则的方式。 了解JSF周期的各个阶段,这可能对您有所帮助。

+1

请注意,OP的特殊问题与您当前最后一个问题中提到的问题**无关**。仅仅因为你发现它“冒犯”而下调技术上有效的答案也没有什么意义。也许你应该接受这样一个事实,即你根本不了解基本HTTP在其核心中的工作原理以及JSF如何抽象(太多)。 – BalusC

0

您可以使用H:dataTable中不填充值在恢复阶段,它填充了的UpdateModel pahse后