ber*_*tie 38 jsf converter selectonemenu jsf-2
我有理解如何有效地使用JSF 2中的选择和POJO /实体.例如,我试图Warehouse通过下面的下拉列表选择一个实体:
<h:selectOneMenu value="#{bean.selectedWarehouse}">
<f:selectItem itemLabel="Choose one .." itemValue="#{null}" />
<f:selectItems value="#{bean.availableWarehouses}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
以下托管bean:
@Named
@ViewScoped
public class Bean {
private Warehouse selectedWarehouse;
private List<SelectItem> availableWarehouses;
// ...
@PostConstruct
public void init() {
// ...
availableWarehouses = new ArrayList<>();
for (Warehouse warehouse : warehouseService.listAll()) {
availableWarehouses.add(new SelectItem(warehouse, warehouse.getName()));
}
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
请注意,我使用整个Warehouse实体作为值SelectItem.
当我提交表单时,会失败并显示以下消息:
'null Converter'的转换错误设置值'com.example.Warehouse@cafebabe'.
我希望Warehouse当我将它包装在一个中时,JSF可以将正确的对象设置为我的托管bean SelectItem.将我的实体包装在里面SelectItem意味着跳过Converter为我的实体创建一个.
Converter每当我想在我的实体中使用实体时,我真的必须使用<h:selectOneMenu>吗?JSF应该可以从可用项列表中提取所选项.如果我真的必须使用转换器,那么实际的方法是什么?到目前为止,我想到了这个:
Converter为实体创建实现.getAsString().我想我不需要这个,因为它的label属性SelectItem将用于显示下拉选项标签.getAsObject().我认为这将用于返回正确的SelectItem或实体,具体取决于托管bean中定义的所选字段的类型.该getAsObject()混淆了我.有效的方法是什么?拥有字符串值,如何获取关联的实体对象?我应该根据字符串值从服务对象查询实体对象并返回实体吗?或者也许某种程度上我可以访问构成选择项的实体列表,循环它们以找到正确的实体,并返回实体?
这是什么常规方法?
Bal*_*usC 69
JSF生成HTML.HTML在Java方面基本上是一个大的String.要在HTML中表示Java对象,必须将它们转换为String.此外,提交HTML表单时,会将提交的值视为StringHTTP请求参数.在封面下,JSF从HttpServletRequest#getParameter()返回的内容中提取它们String.
要在非标准Java对象之间进行转换(即不是a String,Number或者BooleanEL具有内置转换,或者DateJSF提供内置<f:convertDateTime>标记),您必须提供自定义Converter.在SelectItem所有有没有特殊的目的.它只是JSF 1.x的遗留物,当它无法List<Warehouse>直接提供给它时<f:selectItems>.它对标签和转换也没有特殊处理.
您需要以getAsString()这样的方式实现方法,即所需的Java对象以唯一的 String 表示形式表示,该表示可以用作HTTP请求参数.通常,此处使用技术ID(数据库主键).
public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
if (modelValue == null) {
return "";
}
if (modelValue instanceof Warehouse) {
return String.valueOf(((Warehouse) modelValue).getId());
} else {
throw new ConverterException(new FacesMessage(modelValue + " is not a valid Warehouse"));
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,在null/empty模型值的情况下返回空字符串是重要的并且是javadoc所必需的.另请参阅使用"请选择"f:在ap:selectOneMenu中使用null /空值的selectItem.
你需要实现getAsObject()以这样的方式,恰好是String由返回的表示getAsString()可以转换回正好指定为同一个Java对象modelValue中getAsString().
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return warehouseService.find(Long.valueOf(submittedValue));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(submittedValue + " is not a valid Warehouse ID"), e);
}
}
Run Code Online (Sandbox Code Playgroud)
换句话说,您必须在技术上能够将返回的对象作为modelValue参数getAsString()传回,然后将获取的字符串作为无限循环中的submittedValue参数传回getAsObject().
最后只是注释Converterwith @FacesConverter来挂钩有问题的对象类型,然后JSF会在Warehouse类型进入图片时自动处理转换:
@FacesConverter(forClass=Warehouse.class)
Run Code Online (Sandbox Code Playgroud)
那是"规范"的JSF方法.它毕竟不是非常有效,因为它确实也可以抓住该项目<f:selectItems>.但是最重要的一点Converter是它返回一个唯一的 String表示形式,因此Java对象可以通过一个简单的标识来识别,String适合在HTTP和HTML中传递.
JSF实用程序库OmniFaces有一个SelectItemsConverter基于toString()实体结果的工作.这样您就不再需要摆弄getAsObject()昂贵的业务/数据库操作了.有关具体使用示例,请参阅展示.
要使用它,只需将其注册如下:
<h:selectOneMenu ... converter="omnifaces.SelectItemsConverter">
Run Code Online (Sandbox Code Playgroud)
并确保toString()您的Warehouse实体返回实体的唯一表示形式.例如,您可以直接返回ID:
@Override
public String toString() {
return String.valueOf(id);
}
Run Code Online (Sandbox Code Playgroud)
或者更具可读性/可重用性的东西:
@Override
public String toString() {
return "Warehouse[id=" + id + "]";
}
Run Code Online (Sandbox Code Playgroud)
与此问题无关,因为JSF 2.0不再明确要求具有List<SelectItem>as <f:selectItem>值.只是一个List<Warehouse>也足够了.
<h:selectOneMenu value="#{bean.selectedWarehouse}">
<f:selectItem itemLabel="Choose one .." itemValue="#{null}" />
<f:selectItems value="#{bean.availableWarehouses}" var="warehouse"
itemLabel="#{warehouse.name}" itemValue="#{warehouse}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
private Warehouse selectedWarehouse;
private List<Warehouse> availableWarehouses;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
47054 次 |
| 最近记录: |