2010-11-18 4 views
1

In meinem Spring MVC-Projekt habe ich eine Update-Seite für Class1, die eine Liste der Kontrollkästchen format: checkbox anzeigen muss, die an eine Auflistung von Entitäten in Class1 gebunden ist .Spring MVC Checkbox-Tag an die Sammlung gebunden erwartet Objekt, aber Validierung erwartet object.id

Class1.java:

class Class1 { 
    private Set<Class2> set; 
    //... other fields 
} 

In updateclass1.jspx:

<c:forEach items="${allClass2Instances}" var="class2"> 
    <form:checkbox label="${class2.name}" path="set" value="${class2}"/><br/> 
</c:forEach> 

Mit dem Checkbox-Tag, wie oben, wenn ich die Seite anzuzeigen, wird das Kontrollkästchen aktiviert, wenn die Klasse 2 Instanz Teil ist von Set für Klasse1 und nicht aktiviert, wenn dies nicht der Fall ist. Aber wenn ich einreichen Hit, erhalte ich folgende Fehlermeldung:

Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.Set' for property 'set'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "Name 1" from type 'java.lang.String' to type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "Name1" 

Soweit ich sagen kann, wenn die Seite ausgefüllt ist, das Formular: Checkbox-Tag muss eine Instanz den korrekten aktiviert/deaktiviert Wert zu setzen, sondern auf Senden Die JSP sendet ein Array von class2.toString() - Werten an einen Konverter, der die IDs erwartet. Im Gegensatz dazu, wenn ich den Tag wie folgt ändern:

<form:checkbox label="${class2.name}" path="set" value="${class2.id}"/><br/> 

Die Bindung funktioniert gut, aber wenn ich die Update-Seite sehen die Kontrollkästchen nicht aktiviert/unticked richtig, weil der Tag nicht diesen Wert nicht kennen weitergegeben wird, ist die Objekt Identifikation.

Wie mache ich die Bindung nach dem Senden konsistent mit dem, was das Checkbox-Tag erwartet?

Wenn es darauf ankommt - das ist alles in einer Gerüst-Seite von Roo generiert.

Antwort

0

Ich habe herausgefunden, wie man das jetzt funktioniert. Wenn jemand mit einer besseren Lösung kommt, füge es bitte hinzu und ich werde es stattdessen korrekt markieren. $ {InstanceOfClass2} zu bewerten, um verschiedene Dinge an verschiedenen Orten

Das oben beschriebene Problem verursacht wurde durch benötigen:

  1. Zum Zeitpunkt der Auswertung des Tags, <form:checkbox> einen Ausdruck benötigt, die auf eine tatsächliche Instanz ausgewertet der Klasse 2
  2. nach dem Tag abgeschlossen ist, muss der Wert des erzeugten Attribut <input type="checkbox"> Tag auf eine numerische ID Feld einer Instanz von Klasse 2

die Lösung gleich sein sollte fügen Sie einen Konverter zu meinem Class1Controller, zB:

Converter<Class2, String> getClass2Converter() { 
    return new Converter<Class2, String>() { 
     public String convert(Class2 instance) { 
      return "" + instance.getId(); 
     } 
    }; 
} 

So der Ausdruck $ {InstanceOfClass2} wertet auf eine Klasse 2-Instanz für die Checkbox-Tag, aber wenn es darum geht die eigentliche HTML zu schreiben, ist eine numerische ID umgewandelt.

Dieser Ansatz ist sehr chaotisch bei der Arbeit mit Roo. Alle anderen Scaffolds, die sich auf Class1 beziehen, wollen dann denselben Converter verwenden, also habe ich überall einen ganzen Haufen IDs gesehen, an denen man Class2.name oder andere solche Felder sehen möchte. Ich löste das, indem ich das Spring Roo <field:display> benutzerdefinierte Tag änderte - fügte ein Attribut fmtCollectionToString hinzu, das das Tag zwingt, die Sammlungen zu bewerten, indem es sie iteriert und toString auf jedem Element aufruft, anstatt spring:eval für die gesamte Sammlung aufzurufen, die auch zu enden scheint mit dem Konverter wird aufgerufen.

Wie ich schon sagte, wurden bessere Lösungen sehr geschätzt! Wenn es einen Weg gibt, Konverter sich unter verschiedenen Umständen anders zu verhalten, zum Beispiel - will es immer noch hören.

Verwandte Themen