6

ObjectAのリストを持つオブジェクトがありますObjectBTreeMap中にありObjectBます。これTreeMapには、Stringキーとしてのキーと、値としてListの別のオブジェクトのがありObjectCます。これTreeMaplist内部はとをjsp使用して表示されてs: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">

日食の「変数」ビューのオブジェクト構造は次のことを示しています

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の「変数」ビューでは、allPlainFieldsの値は**:**{Key1=}です。

編集(2013年2月27日)

これを試しましたが、機能しませんでした。値は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のメソッドactionが呼び出されます。マップはここに記載されているように印刷されます:

public String updateTreeMap(){

    for (Map.Entry<String, ObjectCList> entry : testTreeMap.entrySet())
    {
        System.out.println(entry.getKey() + "/" + entry.getValue());
    }

    return SUCCESS;

}

「印刷」とは:mykey1 /mykey2/つまりnull値

以下の画面は、jspで入力される値を示しています 値を示す画面はjspで表示されます

4

2 に答える 2

6

最新のアップデートによると。Struts2を使用している場合TreeMap、その中の要素のタイプを正しく判別できません。の宣言をtestTreeMapからTreeMapに変更しMapます。

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

または、注釈testTreeMapcom.opensymphony.xwork2.util.Element付けて、マップ内の要素がどのタイプであるかをStruts2に通知します。

@Element(value = ObjectCList.class)
private TreeMap<String,ObjectCList> testTreeMap = new TreeMap<String,ObjectCList>();
于 2013-02-27T09:37:11.017 に答える
5

私は興味を持ち、他の実験をしました。

インターフェイス( 、)として、またはそれらの実装(、、 )として宣言された、sList内のListsもMaps内Mapのs(およびすべての補間)も、によって正しく処理されないことがわかりました。ListMapArrayListHashMapTreeMapXWork Converter

すべてのテストケースが失敗しました。

たぶんそれは私のせいです、もしそうなら、私たちは本当にOGNLここに何人かの専門家を必要とします、なぜならウェブ全体でこれについて話すことは何もないからです。

それから私はそれがうまくいくとかなり確信していたことを試しました:純粋な方法で、この情報をカスタムオブジェクトOOPにカプセル化します。

そしてそれはうまくいきました:)

それ以外の

private ArrayList<ArrayList<String>> outerObjects;

アクションで使用できます

private ArrayList<OuterObject> outerObjects; 

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

OuterObjectの定義:

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

InnerObject定義

public class InnerObject{
    String innerField;

    /* GETTERS AND SETTERS */       
    public String getInnerField() {         
        return innerField;
    }
    public void setInnerField(String innerField) {
        this.innerField = innerField;
    }

}

プリセット値をテストするためのアクションのオプションの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);

JSP:_

    <s:form>
        <s:textfield name="outerObjects[0].innerObjects[0].innerField" />
        <s:submit/>
    </s:form>

(反復するときは、単にsとsに使用[%{#stat.index}]します)List['%{#stat.index}']Map

同じソリューションがあらゆる種類の反復可能な構造に適用できます(おそらく、メソッドを呼び出すGuava必要があるものを除く)。.create()

もちろん、これはすべての場合に便利というわけではありません。あなたの例では、すでに巨大な構造があり、これはほぼ2倍になりますが、それは機能します。OOPであり、OGNLは(名前のために)より明確になりますが、唯一のようです。仕方。

注:クラスは、オブジェクトの自動配線に失敗するInner Classes別のケースではなく、実際のスタンドアロンクラスである必要があります。OGNL

お役に立てば幸い


編集

その場合に必要なのは、もう1つのレベルだけです。

これを変える:

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

これに

private TreeMap<String,ObjectX> allPlainFields;

ObjectXであるプライベートフィールドを含むを作成しますList<ObjectC>

それが動作します。

于 2013-02-21T17:59:10.933 に答える