Struts2:更新Map中“List Of Objects”的值

时间:2013-02-21 16:06:32

标签: java collections struts2 treemap ognl

有一个对象ObjectA,其中包含ObjectB列表。 TreeMap内有一个ObjectB。此TreeMap有一个String作为键,另一个List的{​​{1}}作为值。 ObjectC内部TreeMaplist已使用jsps:iterator显示在s:textfield上,并且正确显示。即s:textfield中的“值”是正确的。现在,修改文本字段时出现问题。我们如何捕获动作类中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....

JSP代码

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

HTML呈现:     <input type="text" id="review-act1_objA_objB_0__allPlainFields_'Key1'__6__attr112" value="Correct Value" name="objA.objB[0].allPlainFields['Key1'][0].attr112">

eclipse的“VAriables”视图中的对象结构显示

objA    Object A  (id=955)  
objB    ArrayList<E>  (id=966)  
    elementData Object[10]  (id=967)    
        [0] ObjectB  (id=968)   
            allPlainFields  TreeMap<K,V>  (id=972)  
                comparator  null    
                descendingMap   null    
                entrySet    TreeMap$EntrySet  (id=979)  
                keySet  null    
                modCount    1   
                navigableKeySet null    
                root    TreeMap$Entry<K,V>  (id=980)    
                size    1   
                values  null    

        [1] ObjectB  (id=969)   
        [2] ObjectB  (id=970)   
        [3] ObjectB  (id=971)   
        [4] null    
        [5] null    
        [6] null    
        [7] null    
        [8] null    
        [9] null    
    modCount    4   
    size    4   

****在Eclipse“Variables”视图中,allPlainFields的值为**:** {Key1 =}

修改(27-FEB-2013)

试过这个,但没有用。这些值出现在jsp上,但是在提交时,它们不会起作用:

Action课程中:

private TreeMap<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();
//get,set and setting two keys in map "mykey1" and "mykey2"

ObjectCList课程中:

private ArrayList<ObjectC> paramMdlList;
 //default constructor, get, set

JSP

<s:form id="test-map" method="post">
<s:iterator value="testTreeMap" var="pMap" status="hStatus">
     <li><label><s:property value="%{#pMap.key}" /></label> 
        <s:iterator value="%{#pMap.value.paramMdlList}" var="pList" status="innerStatus">
            <s:textfield name="testTreeMap['%{#pMap.key}'].paramMdlList[%{#innerStatus.index}].attr111"/>
            <s:textfield name="testTreeMap['%{#pMap.key}'].paramMdlList[%{#innerStatus.index}].attr112"/> 

        </s:iterator>


    </li>

</s:iterator>
<s:submit value=" " type='button' id="btnh1" action="saveTreeMap">
            <span>Save TreeMap</span>
</s:submit>
</s:form>

提交表单后,会调用updateTreeMap的{​​{1}}方法。地图按照here所述打印:

action

}

什么是“打印”:     mykey1 /     mykey2 / 即空值

下面的屏幕显示了jsp 中的值 screen showing values come in jsp

2 个答案:

答案 0 :(得分:6)

根据您的最新动态。如果您正在使用TreeMap Struts2无法正确确定其中的元素类型。将testTreeMap的声明从TreeMap更改为Map

private Map<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();

或使用testTreeMap注释注释com.opensymphony.xwork2.util.Element告诉Struts2地图中的元素是什么类型。

@Element(value = ObjectCList.class)
private TreeMap<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();

答案 1 :(得分:5)

我变得好奇并做了其他实验。

我发现List内的ListMap内的Map s(以及所有内插)都没有声明为接口({{1} }},List),或Map正确处理其实现(ArrayListHashMapTreeMap)。

所有测试用例都失败了。

也许这是我的错,如果是这样的话,我们真的需要一些XWork Converter专家,因为在整个网络上都没有谈论这个。

然后我尝试了我非常确定会有效的方法:以纯OGNL方式将此信息封装在自定义对象中。

它有效:)

而不是

OOP

您可以在操作

中使用
private ArrayList<ArrayList<String>> outerObjects;

OuterObject 定义:

private ArrayList<OuterObject> outerObjects; 

/* GETTERS AND SETTERS */
public ArrayList<OuterObject> getOuterObjects() {
    return outerObjects;
}
public void setOuterObjects(ArrayList<OuterObject> outerObjects) {
    this.outerObjects = outerObjects;
}

InnerObject 定义:

/* 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;
    }

}

JSP

        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> 代表[%{#stat.index}] s List代表['%{#stat.index}'] s)

相同的解决方案适用于各种可迭代结构(可能除了需要调用Map方法的Guava内容之外)。

当然这在每种情况下都不方便,在你的例子中你已经有了一个巨大的结构并且这几乎会加倍,但它有效,它是OOP,你的OGNL会更清晰(因为但名称似乎是唯一的方式。

注意:类必须是真正的独立类,而不是.create()Inner Classes无法自动装配对象的另一种情况。

希望有所帮助


编辑

您需要的只是另一个级别:

改变这个:

OGNL

到这个

private TreeMap<String,List<ObjectC>> allPlainFields;

并创建一个private TreeMap<String,ObjectX> allPlainFields; ,其中包含一个ObjectX的私有字段。

它会起作用。