tengo la forma siguiente (simplificado) en uno de mi punto de vista:¿Cuáles son las mejores estrategias de conversión de primavera en el caso de una Cadena para convertir a un conjunto de objetos?
<form:form commandName="entry" method="POST">
<form:input type="text" path="name"/>
<form:input type="text" path="tags" />
<input type="submit" value="Submit"/>
</form:form>
que va a ser unen a la siguiente JavaBean:
public class Entry {
private String name;
private List<Tag> tags = new LinkedList<Tag>();
// setters and getters omitted
}
porque quiero tomar el uso totalmente nuevo de lujo características de la primavera 3, que estoy usando el controlador de anotación impulsada para recibir la solicitud POST:
@Controller
@RequestMapping("/entry")
public class EntryController {
@RequestMapping(method = RequestMethod.GET)
public ModelAndView show() {
ModelAndView mav = new ModelAndView("entry");
mav.addObject(new Entry());
return mav;
}
@RequestMapping(method = RequestMethod.POST)
public String add(@ModelAttribute("entry") @Valid Entry entry,
BindingResult result) {
// check validation from Binding result
// execute method on business beans: adding this entry to the system
// return a view if correct
}
}
Como se puede ver, necesito para convertir mi texto de entrada (que loo k como tag1, tag2, tag3
) como una lista de etiquetas, definen así:
public class Tag {
private String name;
// setter and getter omitted
}
Hay varias estrategias para hacer esto con Spring 3.0:
( puesto mucho este momento, las preguntas están en negrita)
El más simple
Programación de una nueva propiedad tagsAsText
tener un captador/definidor como cadena:
public class Entry {
// ...
public void setTagsAsText(String tags) {
// convert the text as a list of tags
}
public String getTagsAsText() {
// convert list of tags to a text
}
}
Este enfoque tiene dos inconvenientes:
- que incluyen la lógica de conversión en mi objeto de dominio, ¿es un problema?
- ¿Dónde puedo acceder al
BindingResult
en caso de error en la cadena?
El uso de BeanInfo
También puedo utilizar un BeanInfo para mi café en grano:
public class EntryBeanInfo extends SimpleBeanInfo {
public PropertyDescriptor[] getPropertyDescriptors() {
try {
@Override
PropertyDescriptor tagsDescriptor = new PropertyDescriptor("tags", Entry.class) {
@Override
public PropertyEditor createPropertyEditor(Object bean) {
return new EntryTagListEditor(Integer.class, true);
};
};
// omitting others PropertyDescriptor for this object (for instance name)
return new PropertyDescriptor[] { tagListDescriptor };
}
catch (IntrospectionException ex) {
throw new Error(ex.toString());
}
}
}
Y declarar un convertidor
public class EntryTagListEditor extends PropertyEditorSupport {
public void setAsText(String text) {
// convert the text to a list of Tag
}
public String getAsText() {
// convert the list of Tag to a String
}
}
Este enfoque tiene también dos inconvenientes:
- Necesito editar mi BeanInfo cada vez que agrego/cambio mi clase de entrada. o ¿hay alguna manera de tener una forma sencilla de definir mi BeanInfo (como "de esta propiedad, utilice esto, los demás sólo hacer como de costumbre")
- Dónde puedo acceder a la
BindingResult
en el caso de error en la cuerda?
El uso de convertidor
convertidor utiliza el mecanismo genérico de Java 5:
final class StringToTagList implements Converter<String, List<Tag>> {
public List<Tag> convert(String source) {
// convert my source to a list of Tag
}
}
Este enfoque parece más elegante, pero todavía dos inconvenientes:
- Parece redefino todos los convertidores predeterminados si configuro este convertidor en la Propiedad de
ConversionServiceFactoryBean
, es Hay alguna forma de mantener los convertidores predeterminados? - (nuevamente) ¿Dónde puedo acceder al
BindingResult
en caso de error en la cadena?
Perdón por ser tan largo, pero esta podría ser una discusión interesante sobre la conversión en Spring – Kartoch