0

我正在尝试更新 an 中的值,h:dataTable并且已达到我在单个 POST 中允许的请求参数的限制。对其进行萤火虫攻击后,我看到正在发送整个表以对单行进行更新。我尝试将 移动h:form到仅包围,a4j:commandButton但这不会更新属性值。我想过使用f:ajax,但我在那里看到的所有内容都在谈论ManagedBeans 的变化。这样做的问题是,支持类也在标准 Java 应用程序中使用,所以我想将它保持为一个干净的 POJO,而不是添加对 Java EE 特定库的依赖项。

更新

按照@Luiggi Mendoza 的要求,我已将问题分解为具有两个Java 类和一个xhtml的SSCCE :

测试DT.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>

属性编辑器.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);
  }

}

属性.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):

豆类.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>

面孔-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>

网页.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>

谢谢

4

1 回答 1

0

假设您的updateProperty方法接收一个int参数(或 的类型prop.id),那么您必须使用action而不是actionListener.

解决方案:

<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...
    }
}

两者的区别参考这里:action和actionListener的区别

于 2013-03-27T20:38:37.380 回答