Estoy buscando la forma más fácil y sencilla de vincular y convertir datos en Spring MVC. Si es posible, sin hacer ninguna configuración xml.
Hasta ahora he estado usando PropertyEditors así:
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();
}
}
y
...
public class MyController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Category.class, new CategoryEditor());
}
...
}
Es simple: ambas conversiones se definen en la misma clase y el enlace es sencillo. Si quisiera hacer un enlace general en todos mis controladores, aún podría agregar 3 líneas en mi configuración xml .
Pero Spring 3.x introdujo una nueva forma de hacerlo, utilizando convertidores :
Dentro de un contenedor Spring, este sistema se puede usar como una alternativa a PropertyEditors
Entonces, digamos que quiero usar Convertidores porque es "la última alternativa". Tendría que crear dos convertidores:
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();
}
}
Primer inconveniente: tengo que hacer dos clases. Beneficio: no hay necesidad de lanzar gracias a su carácter genérico.
Entonces, ¿cómo simplemente enlazo los convertidores a los datos?
Segundo inconveniente: no he encontrado ninguna forma simple (anotaciones u otras instalaciones programáticas) para hacerlo en un controlador: nada parecido someSpringObject.registerCustomConverter(...);
.
Las únicas formas que he encontrado serían tediosas, no simples y solo sobre el enlace general de controlador cruzado:
-
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="somepackage.StringToCategory"/> <bean class="somepackage.CategoryToString"/> </set> </property> </bean>
Configuración de Java ( solo en Spring 3.1+ ):
@EnableWebMvc @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override protected void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToCategory()); registry.addConverter(new CategoryToString()); } }
Con todos estos inconvenientes, ¿por qué usar convertidores? Me estoy perdiendo de algo ? ¿Hay otros trucos que no conozco?
Estoy tentado a seguir usando PropertyEditors ... El enlace es mucho más fácil y rápido.
fuente
Respuestas:
No, creo que ha descrito de manera muy exhaustiva tanto PropertyEditor como Converter, cómo se declara y registra cada uno.
En mi opinión, los PropertyEditors tienen un alcance limitado: ayudan a convertir String en un tipo, y esta cadena generalmente proviene de la interfaz de usuario, por lo que tiene sentido registrar un PropertyEditor usando @InitBinder y WebDataBinder.
El convertidor, por otro lado, es más genérico, está destinado a CUALQUIER conversión en el sistema, no solo para las conversiones relacionadas con la interfaz de usuario (String to target type). Por ejemplo, Spring Integration usa un convertidor ampliamente para convertir una carga útil de mensajes al tipo deseado.
Creo que para los flujos relacionados con la interfaz de usuario, los PropertyEditors siguen siendo apropiados, especialmente para el caso en el que necesita hacer algo personalizado para una propiedad de comando específica. Para otros casos, tomaría la recomendación de la referencia de Spring y escribiría un convertidor en su lugar (por ejemplo, para convertir de un ID largo a una entidad, por ejemplo, como muestra).
fuente
fuente
Lo más simple (suponiendo que esté utilizando un marco de persistencia), pero no la forma perfecta es implementar un convertidor de entidad genérico a través de la
ConditionalGenericConverter
interfaz que convertirá entidades utilizando sus metadatos.Por ejemplo, si está utilizando JPA, este convertidor puede buscar si la clase especificada tiene una
@Entity
anotación, y usar un@Id
campo anotado para extraer información y realizar la búsqueda automáticamente usando el valor de cadena proporcionado como Id para la búsqueda.ConditionalGenericConverter
es un "arma definitiva" de la API de conversión de Spring, pero se implementa una vez que pueda procesar la mayoría de las conversiones de entidades, ahorrando tiempo al desarrollador; es un gran alivio cuando solo especifica las clases de entidad como parámetros de su controlador y nunca piensa en implementar un nuevo convertidor (a excepción de los tipos personalizados y no de entidad, por supuesto).fuente
Puede solucionar la necesidad de tener dos clases de convertidor separadas implementando los dos convertidores como clases internas estáticas.
Aún necesitaría registrar ambos por separado, pero al menos esto reduce la cantidad de archivos que necesita modificar si realiza algún cambio.
fuente