Struts2: Aktualisieren der Werte einer “Liste von Objekten” innerhalb einer Map

Es gibt ein Objekt ObjectA mit einer Liste von ObjectB . Es gibt eine TreeMap innerhalb des ObjectB . Diese TreeMap hat einen String als Schlüssel und eine List eines anderen Objekts als Wert. Diese TreeMap und die darin enthaltene list wurden auf dem jsp mit dem s:textfield und s:textfield und korrekt angezeigt. dh die “Werte” innerhalb des s: Textfelds sind korrekt. Jetzt tritt das Problem auf, wenn das Textfeld geändert wird. Wie erfassen wir die geänderten Werte in ObjectC in der Action-class? Mit dem hier angegebenen Code kommt der Schlüssel (“Key1”) in die Aktion, aber der Wert ist null.

Java-Code

 public class ObjectA implements Serializable { private Integer attr1; private List objB; //...getters and setters.... public class ObjectB implements Serializable { private Integer attr11; private TreeMap<String,List> allPlainFields; // ...getters and setters.... public class ObjectC implements Serializable { private Integer attr111; public String attr112; // ...getters and setters.... 

JSP-Code

       

HTML gerendert:

Die Objektstruktur in der Ansicht “VAriables” von Eclipse zeigt :

 objA Object A (id=955) objB ArrayList (id=966) elementData Object[10] (id=967) [0] ObjectB (id=968) allPlainFields TreeMap (id=972) comparator null descendingMap null entrySet TreeMap$EntrySet (id=979) keySet null modCount 1 navigableKeySet null root TreeMap$Entry (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 

**** In der Ansicht “Variablen” von Eclipse lautet der Wert für allPlainFields **: ** {Key1 =}

BEARBEITEN (27-Feb-2013) :

Versucht dies, hat aber nicht funktioniert. Die Werte erscheinen auf Jsp, aber wenn sie gesendet werden, kommen sie nicht zum Einsatz:

Im Action -Bereich:

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

In der ObjectCList class:

 private ArrayList paramMdlList; //default constructor, get, set 

In JSP :

   
  • Save TreeMap

    Wenn das Formular updateTreeMap wird, wird die updateTreeMap Methode der action aufgerufen. Die Karte wird wie hier erwähnt gedruckt:

     public String updateTreeMap(){ for (Map.Entry entry : testTreeMap.entrySet()) { System.out.println(entry.getKey() + "/" + entry.getValue()); } return SUCCESS; 

    }

    Was wird “gedruckt”: mykey1 / mykey2 / ie Nullwerte

    Der folgende Bildschirm zeigt Werte, die in Jsp kommen Bildschirm zeigt Werte in Jsp

       

    Laut deinem letzten Update. Wenn Sie TreeMap Struts2 kann den Typ der darin enthaltenen Elemente nicht korrekt bestimmen. Ändern Sie die Deklaration von testTreeMap von TreeMap in Map .

     private Map testTreeMap = new TreeMap(); 

    Oder testTreeMap com.opensymphony.xwork2.util.Element testTreeMap mit der Annotation com.opensymphony.xwork2.util.Element , um Struts2 mitzuteilen, um welchen Typ es sich bei Elementen in der Karte handelt.

     @Element(value = ObjectCList.class) private TreeMap testTreeMap = new TreeMap(); 

    Ich bin neugierig geworden und habe andere Experimente gemacht.

    Ich fand heraus, dass weder List innerhalb List noch Map s innerhalb Map s (und alle Interpolationen) als Schnittstelle ( List , Map ) deklariert sind, oder wie ihre Implementierungen ( ArrayList , HashMap , TreeMap ) von der XWork Converter korrekt gehandhabt werden XWork Converter .

    Alle Testfälle sind fehlgeschlagen.

    Vielleicht ist es meine Schuld, wenn wir hier wirklich ein paar OGNL Experten brauchen, denn im ganzen Netz wird nicht darüber geredet.

    Dann habe ich versucht, was ich ziemlich sicher hatte, dass das geklappt hätte: Einkapseln dieser Informationen in benutzerdefinierten Objekten , in reiner OOP Weise.

    Und es hat funktioniert 🙂

    Anstatt von

     private ArrayList> outerObjects; 

    Sie können in Ihrer Aktion verwenden

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

    die OuterObject- Definition:

     /* ELSEWHERE IN YOUR PROJECT... */ public class OuterObject{ private ArrayList innerObjects; /* GETTERS AND SETTERS */ public ArrayList getInnerObjects() { return innerObjects; } public void setInnerObjects(ArrayList innerObjects) { this.innerObjects = innerObjects; } } 

    die InnerObject- Definition:

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

    die optionale Methode execute () Ihrer Aktion , um die voreingestellten Werte zu testen:

      InnerObject innerObj1 = new InnerObject(); innerObj1.setInnerField("Inner Value 1"); ArrayList innerObjArrayList = new ArrayList(); innerObjArrayList.add(innerObj1); OuterObject outerObj1 = new OuterObject(); outerObj1.setInnerObjects(innerObjArrayList); outerObjects = new ArrayList(); outerObjects.add(outerObj1); 

    die JSP :

          

    (Beim Iterieren verwenden Sie einfach [%{#stat.index}] für List s und ['%{#stat.index}'] für Map s)

    .create() Lösung ist für jede Art von iterabler Struktur anwendbar (wahrscheinlich außer dem Guava Stuff, für den die Methode .create() aufgerufen werden muss).

    Natürlich ist das nicht in jedem Fall praktisch, in deinem Beispiel hast du bereits eine riesige Struktur und das wird es fast verdoppeln , aber es funktioniert, es ist OOP, dein OGNL wird klarer (wegen Namen) und scheint jedoch das einzige zu sein Weg.

    Hinweis: Die classn müssen echte eigenständige classn und keine Inner Classes , ein weiterer Fall, in dem OGNL die Objekte nicht automatisch mit dem Laufwerk verbinden kann.

    Ich hoffe, das hilft


    BEARBEITEN

    Was Sie dann brauchen, ist nur eine weitere Ebene:

    ändere das:

     private TreeMap> allPlainFields; 

    dazu

     private TreeMap allPlainFields; 

    und erstellen Sie ein ObjectX mit einem privaten Feld, das eine List .

    Es wird klappen.