Java Struts2:更新“a”的值;“对象列表”;在地图里面
有一个对象Java Struts2:更新“a”的值;“对象列表”;在地图里面,java,collections,struts2,treemap,ognl,Java,Collections,Struts2,Treemap,Ognl,有一个对象ObjectA,它有一个ObjectB列表。在ObjectB中有一个TreeMap。此TreeMap具有一个字符串作为键,另一个对象ObjectC的列表作为值。使用s:iterator和s:textfield在jsp上显示了此TreeMap和list内部,并且显示正确。i、 e.s:textfield内的“值”是正确的。现在,修改textfield时会出现问题。我们如何在action类中捕获ObjectC中修改的值?在这里给出的代码中,键(“Key1”)出现在操作中,但值为null J
ObjectA
,它有一个ObjectB
列表。在ObjectB
中有一个TreeMap
。此TreeMap
具有一个字符串作为键,另一个对象ObjectC
的列表作为值。使用s:iterator
和s:textfield
在jsp
上显示了此TreeMap
和list
内部,并且显示正确。i、 e.s:textfield内的“值”是正确的。现在,修改textfield时会出现问题。我们如何在action类中捕获ObjectC中修改的值?在这里给出的代码中,键(“Key1”)出现在操作中,但值为null
Java代码
public class ObjectA implements Serializable {
private Integer attr1;
private List<ObjectB> objB;
//...getters and setters....
public class ObjectB implements Serializable {
private Integer attr11;
private TreeMap<String,List<ObjectC>> allPlainFields;
// ...getters and setters....
public class ObjectC implements Serializable {
private Integer attr111;
public String attr112;
// ...getters and setters....
<s:iterator value="objA.objB" var="currentObjB" status="currentGroupStatus">
<s:iterator value="#currentObjB.allPlainFields" var="parentMap" status="headerStatus">
<s:iterator value="#parentMap.value" var="fieldList" status="fieldStatus">
<s:textfield name="objA.objB[%{#currentGroupStatus.index}].allPlainFields['%{#parentMap.key}'][%{#fieldStatus.index}].attr112"/>
</s:iterator>
</s:iterator>
在ObjectCList
类中:
private TreeMap<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();
//get,set and setting two keys in map "mykey1" and "mykey2"
private ArrayList<ObjectC> paramMdlList;
//default constructor, get, set
提交表单时,调用操作
的updateReemap
方法。地图的打印方式如下所述:
公共字符串updateTreeMap(){
for(Map.Entry:testTreeMap.entrySet())
{
System.out.println(entry.getKey()+“/”+entry.getValue());
}
回归成功;
}
什么是“印刷品”:
mykey1/
我的钥匙2/
i、 e.空值
下面的屏幕显示jsp中的值
我变得好奇,做了其他实验
我发现无论是List
s中的List
s,还是Map
s中的Map
s(以及所有的插值),都没有声明为接口(List
,Map
),或者作为它们的实现(ArrayList
,HashMap
,TreeMap
)由XWork转换器正确处理
所有测试用例都失败了
也许是我的错,如果是这样的话,我们这里真的需要一些OGNL
专家,因为在整个网络中都没有关于这一点的讨论
然后我尝试了我非常确定会奏效的方法:用纯OOP
的方式将这些信息封装在自定义对象中
它成功了:)
而不是
private ArrayList<ArrayList<String>> outerObjects;
用于测试预设值的操作的可选execute()方法:
InnerObject innerObj1 = new InnerObject();
innerObj1.setInnerField("Inner Value 1");
ArrayList<InnerObject> innerObjArrayList = new ArrayList<InnerObject>();
innerObjArrayList.add(innerObj1);
OuterObject outerObj1 = new OuterObject();
outerObj1.setInnerObjects(innerObjArrayList);
outerObjects = new ArrayList<OuterObject>();
outerObjects.add(outerObj1);
对此
private TreeMap<String,ObjectX> allPlainFields;
私有树映射allPlainFields;
并创建一个ObjectX
,其中包含一个作为列表的私有字段
根据您的最新更新,它将起作用。。如果使用的是TreeMap
Struts2,则无法正确确定其中元素的类型。将testTreeMap
的声明从TreeMap
更改为Map
private Map<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();
可能与@Roman重复,另一个链接用于列表中的地图。这是一个列表中的地图中的列表。从逻辑上讲,这应该以类似的方式工作,但令人惊讶的是,事实并非如此。您收到第一个问题的答案了吗?每次你改变结构,我们都应该复制彼此的代码?为什么要多次问同一个问题。通过回答问题获得代表,然后花在赏金上。@Roman,是的,我收到了第一个问题的答案,我接受了。看起来内部集合的另一个级别不起作用。看起来是同一个问题,但事实并非如此。你以前有没有遇到过这样的问题?我不明白,至于我,我从来没有,从来没有使用过这样的表达方式,不必要的复杂性会导致错误和数月、数年的工作。我会尝试一下。但是,当我将s:textfield
更改为
时,我在日志中发现一个错误:设置'objA.objB[0].allPlainFields.get('Key1').get(0).attr112'类com.vm.action.Act1:错误设置表达式'objA.objB[0].allPlainFields.get('Key1').get(0).attr112'值为['testval',]。请注意在testval旁边添加了“,”和一个空格。这是我迄今为止最接近的一次;OGNL尝试了一些东西:)Vicky,我已经接近了很多次(例如List和ArrayList之间存在差异;显然,在第一种情况下,OGNL在尝试“猜测”接口的正确实现时遇到了问题……顺便说一句,仔细想想,您的结构不会“几乎翻倍”,您只需要再增加一个级别。我正在用它更新答案。@Andrea,我已经在您的第一个响应的基础上添加了一个额外的层,我认为,这不重要(?)以下是我在映射级别的两个不同映射中得到的两个不同错误:场景1:意外异常捕获设置'rqpprmmdl.rqGrp[1].pFWrap.allPFields['DefaultHeader'].paramMdlList[7].pValue'
on'classcom.hm.action.Act1
:错误设置表达式'RQPGPMML.rqGrp[1].pFWrap.allPFields['DefaultHeader'].paramMdlList[7].pValue'with value'[Ljava.lang.String;@3b9b2222'
ognl.NoSuchPropertyException:java.lang.String.ParammAllist
Scenario2:意外异常捕获设置'rqPGPrmMdl.rqGrp[1]。pFWrap.allPFields.get('DefaultHeader').ParammAllist[5]。pValue'
在'classcom.hm.action.Act1
:错误设置表达式'rqPGPrmMdl.rqGrp[1].pFWrap.allPFields.get('DefaultHeader').paramMdlList[5].pValue'
with value'[Ljava.lang.String;@3c67312'
ognl.OgnlException:getProperty的源为null(null,“paramMdlList”)
@AndreaLigios:Aleksandr M给出的最后一步是有效的。但是,如果没有你的努力,就不可能达到如此接近解决方案的程度!非常感谢!有什么东西可以感谢你所做的巨大努力吗?如果没有Andrea Lig的努力,就不可能达到如此接近解决方案的程度ios!谢谢你Andrea!只是出于好奇,这个元素符号对番石榴树表
有效吗?这就是开始的地方,早期的树表
被列表地图取代
private ArrayList<OuterObject> outerObjects;
/* GETTERS AND SETTERS */
public ArrayList<OuterObject> getOuterObjects() {
return outerObjects;
}
public void setOuterObjects(ArrayList<OuterObject> outerObjects) {
this.outerObjects = outerObjects;
}
/* ELSEWHERE IN YOUR PROJECT... */
public class OuterObject{
private ArrayList<InnerObject> innerObjects;
/* GETTERS AND SETTERS */
public ArrayList<InnerObject> getInnerObjects() {
return innerObjects;
}
public void setInnerObjects(ArrayList<InnerObject> innerObjects) {
this.innerObjects = innerObjects;
}
}
public class InnerObject{
String innerField;
/* GETTERS AND SETTERS */
public String getInnerField() {
return innerField;
}
public void setInnerField(String innerField) {
this.innerField = innerField;
}
}
InnerObject innerObj1 = new InnerObject();
innerObj1.setInnerField("Inner Value 1");
ArrayList<InnerObject> innerObjArrayList = new ArrayList<InnerObject>();
innerObjArrayList.add(innerObj1);
OuterObject outerObj1 = new OuterObject();
outerObj1.setInnerObjects(innerObjArrayList);
outerObjects = new ArrayList<OuterObject>();
outerObjects.add(outerObj1);
<s:form>
<s:textfield name="outerObjects[0].innerObjects[0].innerField" />
<s:submit/>
</s:form>
private TreeMap<String,List<ObjectC>> allPlainFields;
private TreeMap<String,ObjectX> allPlainFields;
private Map<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();
@Element(value = ObjectCList.class)
private TreeMap<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();