我做了一些研究,可能在org.springframework.web.servlet.tags.form.CheckboxTag的writeTagDetails方法中发现了错误.以下是此方法的有趣部分:
// the concrete type may not be a Boolean - can be String if (boundValue instanceof String) { boundValue = Boolean.valueOf((String) boundValue); } Boolean booleanValue = (boundValue != null ? (Boolean) boundValue : Boolean.FALSE); renderFromBoolean(booleanValue, tagWriter);
因为我使用转换器来显示yes / no而不是true / false,所以boundValue是一个String,并且Boolean.valueOf的调用总是导致false,因为valueOf方法不知道使用的Spring Converter并解释是/不是假的.
我怎样才能用Spring解决这个问题?有人有线索吗?我的大脑已经到了一条死胡同.
只是为了完整性:布尔类型的转换器正在按预期工作(代码见下文).
public class BooleanConverter implements Converter<Boolean,String>, Formatter<Boolean> { @Autowired private MessageSource messageSource; @Override public String print(Boolean object, Locale locale) { return (object) ? messageSource.getMessage("label_true", null, LocaleContextHolder.getLocale()) : messageSource.getMessage("label_false", null, LocaleContextHolder.getLocale()); } @Override public String convert(Boolean source) { return this.print(source, null); } }这似乎有可能克服.那就是你想要一个人类可读的Formatter来向用户显示模型中布尔值的yes / no.但你仍然希望复选框HTML元素工作,看起来那些HTML复选框元素/小部件/ JSP标签需要使用true / false字符串(或布尔Java类型)它似乎不使用转换器来获取任意是/否字符串返回布尔类型.
对我来说这个问题表现为,当模型设置了Boolean.TRUE值时,永远不会勾选复选框的初始状态.这意味着记录的任何读取 – 修改 – 更新(不编辑该字段,当用户未更改时,最终会从“true”转换为“false”).这是由于UI中的初始状态与模型不一致(它显示始终未检查,即假状态),即使模型是真状态也是如此.显示的值是HTML编辑记录屏幕中未选中的复选框,即使模型的值为Boolean.TRUE也是如此.这是因为HTML复选框元素不会将“yes”解释为“true”,并且默认为false(因为这是默认的布尔值).
因此,定义您的Formatter / Converter(就像您已经在做的那样).但是在你的@Controller中添加:
@InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Boolean.class, "friesWithThat", new CustomBooleanEditor(false)); }
这似乎使字符串显示值继续为是/否,但使用并传递给复选框HTML元素的值继续为true / false.
现在,当编辑/更新记录时(在CRUD中),复选框的初始状态与模型一致,保存数据(不编辑任何字段)不会转换复选框状态(这是我对您遇到的问题的理解).
因此,我认为我们可以理解转换器/格式化器用于一般数据显示,而PropertyEditors用于映射模型数据,因此UI小部件需要数据.