无法让JSF dataTable只提交1行

时间:2013-03-27 18:32:04

标签: ajax jsf richfaces

我正在尝试更新h:dataTable中的值,并且在单个POST中允许的请求参数中达到了我的限制。在发现它之后,我看到整个表正在被发送以进行单行更新。我尝试移动h:form以仅围绕a4j:commandButton,但这不会更新属性值。我想过使用f:ajax,但我在那里看到的所有内容都谈到了ManagedBean的变化。问题在于支持类也用在标准的Java应用程序中,所以我想把它保存为一个很好的干净的POJO,而不是在Java EE特定的库上添加依赖项。

更新

根据@Luiggi Mendoza的要求,我已将问题分解为带有两个Java类和一个xhtml的SSCCE

testDT.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 

<h:head></h:head> 
<body>
    <rich:panel id="props">

      <h:form>
      <h:dataTable value="#{propertyEditor.properties}" var="prop">
        <h:column>
          <f:facet name="header">
            <h:outputText value="Value"/>
          </f:facet>
          <h:inputText value="#{prop.value}">
            <f:ajax/>
          </h:inputText>
        </h:column>
        <h:column>
          <a4j:commandButton
              value="Update Property"
              action="#{propertyEditor.updateProperty(prop.id)}"
              render="props"
              execute="@this"/>
        </h:column>
      </h:dataTable>
    </h:form>
    </rich:panel>
</body> 
</html>

PropertyEditor.java

package com.test;

import java.io.Serializable;
import java.util.ArrayList;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class PropertyEditor implements Serializable
{

  private ArrayList<Property> properties = new ArrayList<Property>();

  public PropertyEditor() {}

  @PostConstruct
  private void initProperties() {
    for (int i = 0; i < 510; i++) {
      Property p = new Property(i,"key"+i,"value"+i);
      properties.add(p);
    }
  }

  public ArrayList<Property> getProperties() {
    return properties;
  }

  public void updateProperty(int id) {
    System.out.println("we are updating: " + id);
  }

}

Property.java

package com.test;

public class Property
{
  private int id;
  private String key;
  private String value;
  public Property(int id, String key, String value)
  {
    super();
    this.id = id;
    this.key = key;
    this.value = value;
  }
  public int getId()
  {
    return id;
  }
  public void setId(int id)
  {
    this.id = id;
  }
  public String getKey()
  {
    return key;
  }
  public void setKey(String key)
  {
    this.key = key;
  }
  public String getValue()
  {
    return value;
  }
  public void setValue(String value)
  {
    this.value = value;
  }

}

此外,这是我的配置文件(beans.xml,faces-config.xml和web.xml):

beans.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:plidm="urn:java:org.jboss.seam.security.management.picketlink"
       xmlns:security="urn:java:org.jboss.seam.security"
       xmlns:s="urn:java:ee"
       xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee
      http://jboss.org/schema/cdi/beans_1_0.xsd">

</beans>

faces-config.xml中:

<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    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-facesconfig_2_0.xsd"
    version="2.0">

</faces-config>

的web.xml:

<?xml version="1.0"?>
<web-app version="3.0" 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_3_0.xsd">
  <display-name>DataTableSubmit1</display-name>
  <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>*.xhtml</url-pattern>
  </servlet-mapping>
</web-app>

我的WEB-INF/lib目录中还有以下jar:

common-annotations.jar
commons-beanutils.jar
commons-collections.jar
commons-digester.jar
commons-logging.jar
cssparser-0.9.5.jar
guava.jar
jsf-api-2.0.4-b09.jar
jsf-impl-2.0.4-b09.jar
jstl.jar
richfaces-components-api-4.2.0.Final.jar
richfaces-components-ui-4.2.0.Final.jar
richfaces-core-api-4.2.0.Final.jar
richfaces-core-impl-4.2.0.Final.jar
sac-1.3.jar
standard.jar

我正在使用Java 1.6在JBoss 7.1.1.Final上运行。每次我尝试更新1行时,这仍然会提交整个表格。我知道我可以增加允许的请求参数的数量,但这似乎是一个彻头彻尾的黑客。我在firebug中查看时收到的响应消息是:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response><error><error-name>class java.lang.IllegalStateException</error-name><error-message><![CDATA[More than the maximum number of request parameters (GET plus POST) for a single request ([512]) were detected. Any parameters beyond this limit have been ignored. To change this limit, set the maxParameterCount attribute on the Connector.]]></error-message></error></partial-response>

由于

1 个答案:

答案 0 :(得分:0)

假设您的updateProperty方法收到int参数(或prop.id的类型),那么您必须使用action代替actionListener。< / p>

解决方案:

<h:dataTable value="#{propertyEditor.properties}" var="prop">
    <!-- columns with data -->
    <h:column>
        <a4j:commandButton value="Update Property"
            action="#{propertyEditor.updateProperty(prop.id)}"
            render="props notif"/>
    </h:column>
</h:dataTable>

你的托管bean:

@ManagedBean
@ViewScoped
public class PropertyEditor {

    //attributes, constructor, getters, setters and other methods...

    public void updateProperty(int id) {
        //current implementation...
    }
}

如果您使用CDI,基本上是相同的方法,只是不同的注释:

@Named
@SessionScoped
public class PropertyEditor {

    //attributes, constructor, getters, setters and other methods...

    public void updateProperty(int id) {
        //current implementation...
    }
}

请参阅此处两者之间的差异:Differences between action and actionListener