Kar*_*och 5 java spring converter spring-mvc javabeans
我的一个观点中有以下(简化)表格:
<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>
Run Code Online (Sandbox Code Playgroud)
哪个将绑定到以下JavaBean:
public class Entry {
private String name;
private List<Tag> tags = new LinkedList<Tag>();
// setters and getters omitted
}
Run Code Online (Sandbox Code Playgroud)
因为我想使用Spring 3的所有新功能,我使用注释驱动的控制器来接收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
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我需要将输入文本(看起来像tag1, tag2, tag3)转换为Tag列表,定义如下:
public class Tag {
private String name;
// setter and getter omitted
}
Run Code Online (Sandbox Code Playgroud)
使用Spring 3.0有几种策略可以做到这一点:
(对不起,很长的帖子,问题以粗体显示)
编程新属性tagsAsText以将getter/setter设置为String:
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
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法有两个缺点:
BindingResult字符串中的错误?我也可以为我的bean使用BeanInfo:
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
并声明一个转换器
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
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法也有两个缺点:
BindingResult字符串中的错误?Converter使用Java 5的通用机制:
final class StringToTagList implements Converter<String, List<Tag>> {
public List<Tag> convert(String source) {
// convert my source to a list of Tag
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法看起来更优雅,但仍有两个缺点:
ConversionServiceFactoryBean,有没有办法保留默认转换器?BindingResult字符串中的错误?这是一个经过深思熟虑的问题,即使它会吓跑大多数人:)
无论如何,我认为选项(2)是最接近实际解决方案的。我的第一个建议是将标签列表封装到它自己的模型类中。这将为数据绑定框架提供一个具体的类型来注册,而List和 则String过于笼统。
所以你会有模型类:
public class Entry {
private String name;
private TagList tagList;
}
public class TagList {
private final List<Tag> tags;
public TagList(List<Tag> tags) {
this.tags = tags;
}
public List<Tag> getTags() {
return tags;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你就有了一个PropertyEditor知道如何与 a 相互转换的 a TagList:
public class TagListEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
TagList tagList = // parse from the text value
setValue(tagList);
}
@Override
public String getAsText() {
TagList tagList = (TagList) getValue();
return tagList.toString(); // or whatever
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您需要告诉控制器使用转换器:
@Controller
public class EntryController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(TagList.class, new TagListEditor());
}
// request mappings here
}
Run Code Online (Sandbox Code Playgroud)
我相当确定新的 Spring 3 Converter 框架会产生更优雅的解决方案,但我还没有弄清楚:) 不过,我知道这种方法是有效的。
| 归档时间: |
|
| 查看次数: |
2038 次 |
| 最近记录: |