new SelectItem(Title.MISS, "Miss");
在JSF 2.0之前使用SelectItems通常很繁琐,因为您需要编写代码以使域对象适应SelectItems 。 JSF 2.0进行了很多改进,您现在可以使用EL表达式动态构造SelectItems 。 例如:
<h:selectOneMenu><f:selectItems value="#{customerRepository.all}" var="customer" label="#{customer.name}"/>
</h:selectOneMenu>
这无疑有助于减少样板代码的数量,但是,我仍然认为我们可以做一些事情使SelectItems更加易于使用,尤其是在使用Spring时。 考虑到这一点,我一直在开发<s:selectItems>组件,旨在代替<f:selectItems> 。
我们可以做的第一件事是通过消除指定var属性的需要来帮助减少样板的键入。 使用<s:selectItems>时 ,如果未指定var属性,则默认为item 。 所以上面的代码可以写成:
<h:selectOneMenu><s:selectItems value="#{customerRepository.all}" label="#{item.name}"/>
</h:selectOneMenu>
在上面的示例中,该值绑定到一个存储库接口,该接口返回“ 客户”实体集合 。 与标准<f:selectItems>组件一样,您也可以绑定到Array或DataModel 。 此外,新组件还支持任何以逗号分隔的String值。
<h:selectOneMenu><s:selectItems value="Java, Spring, JavaServer Faces"/>
</h:selectOneMenu>
<s:selectItems>可以帮助的下一件事是空值。 在下拉菜单中需要一个“ Please Select”选项来表示null是很常见的。 在原始JSF中,这通常可能意味着每个组件都需要额外加价:
<h:selectOneMenu><f:selectItem label="--- Please Select ---" noSelectionOption="true" itemValue=""/><s:selectItems value="'{items}"/>
</h:selectOneMenu>
无需为每个元素添加额外的标记,只要将其链接到UISelectOne组件,我们的组件就会自动插入“请选择”选项。 您可以使用includeNoSelectionOption属性来覆盖此行为。 用于“不选择选项”的标签将默认为“-请选择-”,但是您可以通过在您的ApplicationContext中添加一个org.springframework.context.MessageSource来解析和修改代码“ spring.faces” ,从而轻松自定义和国际化此文本。 .noselectionoption” 。
在MessageSource的主题上, <s:selectItems>组件将尽可能尝试使用org.springframework.springfaces.message.ObjectMessageSource创建SelectItem的标签。 我过去在博客中写过有关如何将对象转换为消息的内容,而该组件只是利用了这些想法。
在创建要显示的SelectItem时,新组件对我们有所帮助,但是如何处理表单提交呢? 如何将提交的String选项转换回真实对象 ? 在上面的第一个示例中,我们绑定到JPA 客户实体; 值将显示得很好,但是当您提交表单时,将显示“转换错误”,因为JSF不知道如何从提交的String返回到Customer对象。 通常的答案是开发自己的javax.faces.convert.Converter实现,但这通常是有问题的。 通常,您选择的项目值将是一些复杂的对象,很难完整地表示为String 。
编写将与UISelectOne或UISelectMany组件一起使用的Converter时,可以使用一种有趣的技术。 实际上,您只需要编写代码就可以从Object转换为String ,则可以通过迭代SelectItem并返回单个Object值(转换为String时与您提交的值匹配)来完成从另一个方向的转换。 您可以在 Arjan Tijms的此博客文章中了解有关此想法的更多信息。 将此技术与<s:selectItems>组件一起使用非常简单,只需提供一个itemConverterStringValue属性,该属性将用于创建唯一的getAsString()值:
<h:selectOneMenu><s:selectItems value="#{customerRepository.all}" label="#{item.name}" itemConverterStringValue="#{item.id}"/>
</h:selectOneMenu>
实际上, itemConverterStringValue是可选的。 如果未指定,则将使用对象的toString()方法;对于JPA @Entity ,将自动使用@ID字段。 如果需要,您仍然可以自由编写和附加自己的Converter,在这种情况下, itemConverterStringValue将被忽略。
最后,这是<s:selectItems>可以执行的另一个技巧。 如果选择组件绑定到布尔值或枚举,则可以完全省略value属性。 选择项将基于绑定支持的所有可能选项( 布尔值“是” /“否”或完整的枚举值集)构建。 这也适用于类型化的集合。 例如,以下将显示选项“ Java”,“ Spring”和“ JavaServer Faces”(假设您具有适当的ObjectMessageSource ):
public enum Technology {JAVA, SPRING, JAVASERVER_FACES
}
public class Bean implements Serializable {private Set<Technology> technologies = new HashSet<Technology>();// ... getters and setters
}
<h:selectManyCheckbox value="#{bean.technologies}"><s:selectItems/>
</h:selectManyCheckbox>
参考: 集成Spring和JavaServer Faces:从Phil Webb博客博客中的JCG合作伙伴 Phillip Webb 选择项目 。
翻译自: https://www.javacodegeeks.com/2012/06/spring-jsf-integration-select-items.html