Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OGNL数组和列表索引_Java_Struts2_Ognl - Fatal编程技术网

Java OGNL数组和列表索引

Java OGNL数组和列表索引,java,struts2,ognl,Java,Struts2,Ognl,我正在将此参数发送到struts操作 cdata[1]=酒吧 在我的行动中,我对索引和值感兴趣。 我为CDATA定义了一个getter/setter对,如下所示: public void setCdata(int index, String value){ LOG.info("setData; key="+ key +"; value="+ value); // store index and value; } public String getCdata(int index)

我正在将此参数发送到struts操作

cdata[1]=酒吧

在我的行动中,我对索引和值感兴趣。 我为
CDATA
定义了一个getter/setter对,如下所示:

public void setCdata(int index, String value){
    LOG.info("setData; key="+ key +"; value="+ value);
    // store index and value;
}

public String getCdata(int index){
    return null; // don't really need a setter
}
这是我得到的例外:

2013-04-29 15:38:49,792 [http-apr-8080-exec-3] WARN  com.opensymphony.xwork2.util.logging.commons.CommonsLogger.warn(CommonsLogger.java:60) - Error setting expression 'cdata[1]' with value '[Ljava.
lang.String;@4223d2a4'
ognl.OgnlException: target is null for setProperty(null, "1", [Ljava.lang.String;@4223d2a4)
        at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2309)
        at ognl.ASTProperty.setValueBody(ASTProperty.java:127)
        at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
        at ognl.SimpleNode.setValue(SimpleNode.java:301)
        at ognl.ASTChain.setValueBody(ASTChain.java:227)
        at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
        at ognl.SimpleNode.setValue(SimpleNode.java:301)
        at ognl.Ognl.setValue(Ognl.java:737)
        ...

如果我定义了一个公共成员变量
String[]cdata=new String[1000]
,我在日志中看不到任何异常,但我的setter也没有被调用。如果成员变量是private,我会再次遇到另一个异常。

您最好阅读文档。医生说

JavaBeans支持索引属性的概念。具体而言,这意味着对象具有一组遵循以下模式的方法:


您没有实现所有这些方法

使用以下设置

List<String> cdata = new ArrayList<String>();

public List<String> getCdata() {
   return cdata;
}

public void setCdata(final List<String> cdata) {
    if (cdata == null) {
        this.cdata = new ArrayList<String>();
    } else {
        this.cdata = cdata;
    }
}
List cdata=new ArrayList();
公共列表getCdata(){
返回cdata;
}
公共无效设置cdata(最终列表cdata){
如果(cdata==null){
this.cdata=新的ArrayList();
}否则{
this.cdata=cdata;
}
}
从JSP提交值,如cdata[1]=value等

唯一的要求是要有getter/setter。我已经在Java1.6上测试了这个Tomcat7。您也可以提交类似cdata[0]和cdata[1]的值

或者你可以用地图
private Map data=new HashMap();
公共地图getData(){
返回数据;
}
公共void setData(地图数据){
这个数据=数据;
}
JSP可以有

<s:form action="indexProperty">

    <h3>Test The Map</h3>
    <input type="text" name="data['0']"/>
    <input type="text" name="data['1']"/>

    <s:iterator value="data.entrySet()" var="aData">
        <s:property value="#aData.key" />-<s:property value="#aData.value" />
    </s:iterator>

    <input type="submit" name="submit" value="submit"/>
</s:form>

测试地图
-
填充时没有问题

我的解决方案(相当于一个丑陋的黑客):

我让我的动作类实现
ServletRequestAware
,在动作中从
HttpServletRequest
迭代参数映射,从中获取cdata并解析其索引和值


我必须更改sent参数并对其进行编码,例如
cdata[999]=foobar
cdata\u 999\uuu=foobar
,因为如果它看起来像是struts需要的数组字段,那么action类中就有一个setter/getter。你能给我指一下你提到的文档吗?@LukaszLenart:我相信OP指的是这个文档。是的,文件上是这么说的,但我还是不明白。第二个方法应该做什么?如果它提供了将由ognl设置的数组,那么第四个方法的要点是什么?这意味着您应该创建
String[]getCdata()
,因为您使用的是数组。它也不适用于所有四个方法。它不知道如何初始化字符串[]。我想我必须先初始化数组并知道可能的最高索引,否则我会得到ArrayIndexOutOfBoundsException。索引可能是1000,但我不需要前面999个数组字段的空间。这是浪费空间。它仍然没有解释第四种方法——如果它得到数组,它可以在特定的索引本身设置值,为什么要调用我自己的setter呢?在你的情况下,setter不会被调用。要填充值,您需要调用者可用的空间。如果您需要更多解释,请查看答案。这应该会让你的问题变得清晰。我在每个问题的开头复制了你所有的代码和日志输出。getCdataValues是唯一一个在异常后调用的方法-我刚刚将堆栈跟踪添加到我的原始问题中。@kosmičák我已经编辑了我的答案。唯一的要求是要有合适的getter/setter并使用一个列表是的,这是有效的。。。我在应用程序中的其他地方使用相同的方法,其中传递的参数为。是一个“真实”数组,而不是cdata中的稀疏数组。缺点是,如果索引是1000,而这是传递的唯一字段,那么它会为所有1000个列表项分配空间。我希望ognl/struts能让我自己负责支持/映射这个sparce数组,ognl文档清楚地说明了这一点:我想知道stuts是如何使用ognl的,因为它的行为是相反的。@kosmičák可能是,你可以为此使用列表的特殊自定义实现。。。跟踪NOTNULL元素的大小和索引,并将其他索引视为null。。。。只是一个想法我尝试使用Map cdata并传递cdata['1']。。。Struts查找cdata.set1(…)方法。
private Map<String, String> data = new HashMap<String, String>();

public Map<String, String> getData() {
    return data;
}

public void setData(Map<String, String> data) {
    this.data = data;
}
<s:form action="indexProperty">

    <h3>Test The Map</h3>
    <input type="text" name="data['0']"/>
    <input type="text" name="data['1']"/>

    <s:iterator value="data.entrySet()" var="aData">
        <s:property value="#aData.key" />-<s:property value="#aData.value" />
    </s:iterator>

    <input type="submit" name="submit" value="submit"/>
</s:form>