Mam następujący (uproszczony) forma w jednym z moim zdaniem:Jakie są najlepsze strategie konwertera Spring w przypadku String do przekonwertowania na zestaw obiektów?
<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>
Który będzie wiązać się z poniższym JavaBeans:
public class Entry {
private String name;
private List<Tag> tags = new LinkedList<Tag>();
// setters and getters omitted
}
bo chcę wziąć wykorzystanie wszystkich nowych fantazyjne cechy Spring 3, używam kontroler adnotacji napędzane do otrzymania żądania 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
}
}
Jak widać, trzeba konwertować mój tekst wejściowy (co loo k jak tag1, tag2, tag3
) jako lista Tag zdefiniować tak:
public class Tag {
private String name;
// setter and getter omitted
}
Istnieje kilka strategii, aby to zrobić z wiosny 3,0:
( Niestety długi post, pytania są pogrubioną)
Najprostszym
Programowanie nową właściwość tagsAsText
mieć getter/setter jako wyrażenie:
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
}
}
Podejście to ma dwie wady:
- I obejmuje logikę konwersji w moim obiektu domeny, jest to problem?
- Gdzie mogę uzyskać dostęp do
BindingResult
w przypadku błędu w ciągu znaków?
Korzystanie BeanInfo
mogę też użyć BeanInfo dla mojego Fasola:
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());
}
}
}
i zadeklarować jeden konwerter
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
}
}
Takie podejście ma również dwie wady:
- Muszę edytować moje informacje BeanInfo za każdym razem, gdy dodaję/zmieniam moją klasę wprowadzania. czy jest jakiś sposób, aby w prosty sposób definiować moje BeanInfo (jak „dla tej nieruchomości, to wykorzystać, bo inaczej po prostu zrobić jak zwykle”)
- Gdzie mogę uzyskać dostęp do
BindingResult
w przypadku błędu w ciągu?
Korzystanie Converter
Converter używa ogólnego mechanizmu Java 5:
final class StringToTagList implements Converter<String, List<Tag>> {
public List<Tag> convert(String source) {
// convert my source to a list of Tag
}
}
Podejście wygląda bardziej elegancki, ale nadal dwie wady:
- Wydaje się przedefiniować wszystkie domyślne konwertery, jeśli skonfiguruję ten konwerter w usłudze
ConversionServiceFactoryBean
, to istnieje jakiś sposób na zachowanie domyślnych konwerterów? - (ponownie) Gdzie mogę uzyskać dostęp do
BindingResult
w przypadku błędu w ciągu znaków?
Przepraszam, że tak długo, ale to może być interesująca dyskusja na temat konwersji na wiosnę – Kartoch