Je recherche le moyen le plus simple et le plus simple de lier et de convertir des données dans Spring MVC. Si possible, sans faire de configuration xml.
Jusqu'à présent, j'utilise PropertyEditors comme ceci:
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();
}
}
et
...
public class MyController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Category.class, new CategoryEditor());
}
...
}
C'est simple: les deux conversions sont définies dans la même classe et la liaison est simple. Si je voulais faire une liaison générale sur tous mes contrôleurs, je pourrais toujours ajouter 3 lignes dans ma configuration xml .
Mais Spring 3.x a introduit une nouvelle façon de le faire, en utilisant des convertisseurs :
Dans un conteneur Spring, ce système peut être utilisé comme alternative aux PropertyEditors
Alors disons que je veux utiliser des convertisseurs parce que c'est "la dernière alternative". Il faudrait que je crée deux convertisseurs:
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();
}
}
Premier inconvénient: je dois faire deux cours. Avantage: pas besoin de lancer grâce à la généricité.
Alors, comment puis-je simplement lier les données aux convertisseurs?
Deuxième inconvénient: je n'ai trouvé aucun moyen simple (annotations ou autres facilités de programmation) de le faire dans un contrôleur: rien de telsomeSpringObject.registerCustomConverter(...);
.
Les seuls moyens que j'ai trouvés seraient fastidieux, pas simples et ne concerneraient que la liaison générale entre contrôleurs:
-
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="somepackage.StringToCategory"/> <bean class="somepackage.CategoryToString"/> </set> </property> </bean>
Configuration Java ( uniquement dans Spring 3.1+ ):
@EnableWebMvc @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override protected void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToCategory()); registry.addConverter(new CategoryToString()); } }
Avec tous ces inconvénients, pourquoi utiliser des convertisseurs? Est-ce que je manque quelque chose? Y a-t-il d'autres astuces dont je ne suis pas au courant?
Je suis tenté de continuer à utiliser PropertyEditors ... La liaison est beaucoup plus simple et rapide.
la source
Réponses:
Non, je pense que vous avez décrit de manière très complète PropertyEditor et Converter, comment chacun est déclaré et enregistré.
Dans mon esprit, PropertyEditors a une portée limitée - ils aident à convertir String en type, et cette chaîne provient généralement de l'interface utilisateur, et donc enregistrer un PropertyEditor à l'aide de @InitBinder et de WebDataBinder a du sens.
Le convertisseur, quant à lui, est plus générique, il est destiné à TOUTE conversion dans le système - pas seulement pour les conversions liées à l'interface utilisateur (chaîne en type cible). Par exemple, Spring Integration utilise un convertisseur pour convertir une charge utile de message en un type souhaité.
Je pense que pour les flux liés à l'interface utilisateur, PropertyEditors est toujours approprié, en particulier dans le cas où vous devez faire quelque chose de personnalisé pour une propriété de commande spécifique. Pour les autres cas, je prendrais la recommandation de la référence Spring et j'écrirais un convertisseur à la place (par exemple, pour convertir un identifiant long en une entité, par exemple, comme un échantillon).
la source
la source
Le plus simple (en supposant que vous utilisez un framework de persistance), mais pas le moyen idéal, consiste à implémenter un convertisseur d'entité générique via
ConditionalGenericConverter
interface qui convertira les entités en utilisant leurs métadonnées.Par exemple, si vous utilisez JPA, ce convertisseur peut rechercher si la classe spécifiée a une
@Entity
annotation et utiliser un@Id
champ annoté pour extraire des informations et effectuer la recherche automatiquement en utilisant la valeur String fournie comme Id pour la recherche.ConditionalGenericConverter
est une «arme ultime» de l'API de conversion Spring, mais mise en œuvre une fois qu'elle sera capable de traiter la plupart des conversions d'entités, ce qui fait gagner du temps aux développeurs - c'est un grand soulagement lorsque vous spécifiez simplement des classes d'entités comme paramètres de votre contrôleur et que vous ne pensez jamais à l'implémentation un nouveau convertisseur (sauf pour les types personnalisés et non-entité, bien sûr).la source
Vous pouvez en quelque sorte contourner le besoin d'avoir deux classes de convertisseur distinctes en implémentant les deux convertisseurs en tant que classes internes statiques.
Vous devrez toujours les enregistrer séparément, mais au moins cela réduit le nombre de fichiers que vous devez modifier si vous apportez des modifications.
la source