2013-04-04 67 views
0

我需要在载入jsf页面之前执行Web服务(方法)调用。该调用将返回必须在我的jsf页面上显示的输入字段列表。用户可以填写表单,然后点击下一步,我需要将表单中输入的值发送回另一个Web服务(方法)。 我的方法是为jsf页面(包含一个空白表单和一个绑定到bean)的请求作用域bean,并在我的表单方法的setter方法中执行web服务调用并动态创建UIInput字段
JSF上的动态字段

//call web service 
//Loop 
    UIInput input = new HtmlInputText(); 
    //set unique Id 
    form.getChildren().add(input); 
//End Loop 

它确实创建了输入字段,但是如果我执行浏览器回来或刷新它不断添加输入字段。很明显,我的做法是错误的。
此外,我发现,当我试图让这些动态创建的输入字段中的值上提交的行动像

List<UIComponent> dynamicFields = form.getChildren(); 
for(int i=0;i<form.getChildCount();i++){ 
    if("javax.faces.Input".equals(componentFamily)){ 
     UIInput input = (UIInput)dynamicFields.get(i); 
     System.out.println("Input Field: ID = "+input.getId() + " , Value="+ input.getValue()); 
     } 
} 

领域的ID是正确打印,但是值始终为空。显然这样做都是错误的。

请让我知道什么时候以及在什么时候做我创建领域,我怎么捕捉使用JSF 2.0 PS上午这些值,JDeveloper中,Glassfish和/或Weblogic Server的

+0

什么是你的情况的动态领域的工作有什么好处?为什么你不是简单地使用循环,并在视图中静态创建组件? – Bardelman 2013-04-04 13:43:30

+0

好吧,原因是我不会总是使用单一类型的输入。 Web服务也返回我输入的类型。我将使用某种开关来构建必要的表单。 – 2013-04-04 16:46:11

+0

那么,我想使用组件的动态添加(对于我来说,我有另一个具体的原因),但它似乎有很多问题在这个问题上,也是一个糟糕的文档。如果你找不到解决方案,你可以用一个 jstl标签来制作你需要的静态开关(我猜你已经知道了:D)。 – Bardelman 2013-04-04 17:12:34

回答

-1

此问题的原因的范围你如果它是@RequestScoped,则表示每次刷新或调用页面时要再次调用post constuctor(@PostConstuct)方法,因此再次创建该作业并为空值您应该将输入字段添加到每个输入字段值表达式以将值存储在其中。

private String inputValue; //setter() getter() 
    UIInput input = new HtmlInputText(); 

    @PostCostruct 
    public void addInput() 
    { 
     // your previos create and add input fields to the form + setting value expression 
     Application app = FacesContext.getCurrentInstance().getApplication(); 
     input.setValueExpression("value",app.getExpressionFactory().createValueExpression(
        FacesContext.getCurrentInstance().getELContext(), "#{bean.inputValue}", String.class)); 
    } 

正确的答案,如果你正在使用绑定不要使用请求范围内使用会话范围,它会与您合作,获取数据不为空时检索值。

+0

不好的建议。组件实例是请求作用域。如果在同一会话的多个浏览器选项卡/窗口中打开相同的视图,将它们绑定到会话作用域中的bean只会导致“重复的组件ID”错误,或者至少会导致严重的JSF状态完整性问题。您必须**将组件实例绑定到请求作用域bean。视图范围也可以,但是这需要最少的JSF 2.2(或者在Mojarra 2.1.18版本中)由于鸡蛋问题1492导致在视图构建期间重新创建视图范围的bean。 – BalusC 2013-04-24 11:08:20

0

从你的问题我不能确定你希望从你的web服务获得什么样的数据,以及你想要渲染它的是什么样的组件。我在下面的答案假设你总是会收到一个列表的字符串,你会在文本框中显示它们。

一种可能的方法是调用web服务并在@PostConstruct方法中获取数据,将这些数据放入列表中,然后将数据呈现在数据表中。下面的代码。

豆:

@ManagedBean(name="bean") 
@ViewScoped 
public class YourBean implements Serializable { 


private static final long serialVersionUID = 1L; 

private List<String> values = new ArrayList<String>(); 

    //The method below @PostConstruct is called after the bean is instantiated 
    @PostConstruct 
    public void init(){ 
      //fetch data from source webservice, save it to this.values 
    } 

    public void save(){ 
     for(String s: this.values) 
      // send s to destination webservice 
    } 

    public List<String> getValues(){ 
     return this.values; 
    } 

    public void setValues(List<String> values){ 
     this.values = values; 
    }  

} 

XHTML摘录:

<h:form> 
    <h:dataTable value="#{bean.values}" var="s"> 
      <h:column> 
       <h:inputText value="#{s}" /> 
      </h:column> 
    </h:dataTable> 
    <h:commandButton value="Save" action="#{bean.save}" /> 
</h:form>