Ich suche nach der einfachsten und einfachsten Möglichkeit, Daten in Spring MVC zu binden und zu konvertieren. Wenn möglich, ohne eine XML-Konfiguration vorzunehmen.
Bisher habe ich PropertyEditors wie folgt verwendet:
public class CategoryEditor extends PropertyEditorSupport {
// Converts a String to a Category (when submitting form)
@Override
public void setAsText(String text) {
Category c = new Category(text);
this.setValue(c);
}
// Converts a Category to a String (when displaying form)
@Override
public String getAsText() {
Category c = (Category) this.getValue();
return c.getName();
}
}
und
...
public class MyController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Category.class, new CategoryEditor());
}
...
}
Es ist einfach: Beide Konvertierungen werden in derselben Klasse definiert, und die Bindung ist unkompliziert. Wenn ich eine allgemeine Bindung für alle meine Controller durchführen wollte, konnte ich meiner XML-Konfiguration immer noch 3 Zeilen hinzufügen .
Mit Spring 3.x wurde jedoch mithilfe von Konvertern eine neue Methode eingeführt :
Innerhalb eines Spring-Containers kann dieses System als Alternative zu PropertyEditors verwendet werden
Nehmen wir also an, ich möchte Konverter verwenden, weil dies "die neueste Alternative" ist. Ich müsste zwei Konverter erstellen :
public class StringToCategory implements Converter<String, Category> {
@Override
public Category convert(String source) {
Category c = new Category(source);
return c;
}
}
public class CategoryToString implements Converter<Category, String> {
@Override
public String convert(Category source) {
return source.getName();
}
}
Erster Nachteil: Ich muss zwei Klassen machen. Vorteil: Dank der Großzügigkeit muss nicht gegossen werden.
Wie binde ich dann einfach Daten an die Konverter?
Zweiter Nachteil: Ich habe keine einfache Möglichkeit (Anmerkungen oder andere programmatische Funktionen) gefunden, dies in einer Steuerung zu tun: nichts Vergleichbares someSpringObject.registerCustomConverter(...);
.
Die einzigen Möglichkeiten, die ich gefunden habe, wären mühsam, nicht einfach und nur in Bezug auf die allgemeine Cross-Controller-Bindung:
-
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="somepackage.StringToCategory"/> <bean class="somepackage.CategoryToString"/> </set> </property> </bean>
Java-Konfiguration ( nur in Spring 3.1+ ):
@EnableWebMvc @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override protected void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToCategory()); registry.addConverter(new CategoryToString()); } }
Warum sollten Sie bei all diesen Nachteilen Konverter verwenden? Vermisse ich etwas Gibt es andere Tricks, die mir nicht bekannt sind?
Ich bin versucht, PropertyEditors weiter zu verwenden ... Die Bindung ist viel einfacher und schneller.
quelle
Antworten:
Nein, ich denke, Sie haben sowohl PropertyEditor als auch Converter sehr ausführlich beschrieben, wie jeder deklariert und registriert wird.
In meinen Augen ist der Umfang von PropertyEditors begrenzt. Sie helfen dabei, Zeichenfolgen in einen Typ zu konvertieren. Diese Zeichenfolge stammt normalerweise von der Benutzeroberfläche. Daher ist die Registrierung eines PropertyEditors mithilfe von @InitBinder und WebDataBinder sinnvoll.
Der Konverter hingegen ist allgemeiner und für JEDE Konvertierung im System vorgesehen - nicht nur für Konvertierungen im Zusammenhang mit der Benutzeroberfläche (Zeichenfolge zum Zieltyp). Beispielsweise verwendet Spring Integration einen Konverter in großem Umfang, um eine Nachrichtennutzlast in einen gewünschten Typ zu konvertieren.
Ich denke, für UI-bezogene Flows sind PropertyEditors immer noch geeignet, insbesondere für den Fall, dass Sie für eine bestimmte Befehlseigenschaft etwas Benutzerdefiniertes tun müssen. In anderen Fällen würde ich die Empfehlung aus der Spring-Referenz übernehmen und stattdessen einen Konverter schreiben (z. B. um beispielsweise von einer Long-ID in eine Entität zu konvertieren).
quelle
quelle
Die einfachste (vorausgesetzt, Sie verwenden ein Persistenz-Framework), aber nicht die perfekte Möglichkeit besteht darin, einen generischen Entitätskonverter über eine
ConditionalGenericConverter
Schnittstelle zu implementieren , die Entitäten mithilfe ihrer Metadaten konvertiert.Wenn Sie beispielsweise JPA verwenden, überprüft dieser Konverter möglicherweise, ob die angegebene Klasse
@Entity
Anmerkungen enthält, und verwendet ein mit@Id
Anmerkungen versehenes Feld, um Informationen zu extrahieren und die Suche automatisch durchzuführen, wobei der angegebene String-Wert als ID für die Suche verwendet wird.ConditionalGenericConverter
ist eine "ultimative Waffe" der Spring-Konvertierungs-API, wird jedoch implementiert, sobald die meisten Entitätskonvertierungen verarbeitet werden können, was Entwicklerzeit spart. Dies ist eine große Erleichterung, wenn Sie nur Entitätsklassen als Parameter Ihres Controllers angeben und nie an die Implementierung denken ein neuer Konverter (außer natürlich für benutzerdefinierte und Nicht-Entitätstypen).quelle
Sie können die Notwendigkeit von zwei separaten Konverterklassen umgehen, indem Sie die beiden Konverter als statische innere Klassen implementieren.
Sie müssten beide weiterhin separat registrieren, aber dies verringert zumindest die Anzahl der Dateien, die Sie ändern müssen, wenn Sie Änderungen vornehmen.
quelle