这两天在做之前写的公共构件的维护页面,其中遇到一个不少棘手的问题,其中有一个就是h:selectOneMenu 报Value is not valid错误。我当时是在父页面中定义了一个省和城市两个下拉列表做的级联,子页面同样也定义了省和城市两个级联下拉列表。父页面没问题,子页面在做选择省时,城市是不改变的,而且后台报省下拉列表Value is not valid。经过审核标签,修改id等方法都不能解决。最后,觉得跟踪到jsf源码中一看究竟,发现在UISelectOne的validateValue方法中add进的消息。仔细跟踪终于发现了错误,而且是一个让俺苦笑不得的错误。由于省和城市的在code在数据库中的类型为char(6),所以在不够6位的补空格。不知为什么在子页面中选中下拉列表的值比下拉列表Items中对应的值少个空格,所以在jsf生命周期中验证错误,而无法调用managed Bean。
现在我们分析一下这个问题。前两篇中我们说到了jsf的生命周期,每次请求都是要先经过验证的,h:selectOneMenu的验证方法:
static boolean matchValue(FacesContext ctx,
UIComponent component,
Object value,
Iterator items,
Converter converter) {
while (items.hasNext()) {
SelectItem item = (SelectItem) items.nex