Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 如何从数据库中填充h:selectOneMenu的选项?_Database_Jsf_Selectonemenu - Fatal编程技术网

Database 如何从数据库中填充h:selectOneMenu的选项?

Database 如何从数据库中填充h:selectOneMenu的选项?,database,jsf,selectonemenu,Database,Jsf,Selectonemenu,我正在创建一个web应用程序,您必须从数据库中读取对象/实体列表,并将其填充到JSF中。我无法编写此代码。有人能告诉我怎么做吗 我知道如何从数据库中获取列表。我需要知道的是,如何在中填充此列表 ...? 查看页面 <h:selectOneMenu id="selectOneCB" value="#{page.selectedName}"> <f:selectItems value="#{page.names}"/> </h:selectOneMenu&g

我正在创建一个web应用程序,您必须从数据库中读取对象/实体列表,并将其填充到JSF
中。我无法编写此代码。有人能告诉我怎么做吗

我知道如何从数据库中获取
列表。我需要知道的是,如何在
中填充此列表


...?

查看页面

<h:selectOneMenu id="selectOneCB" value="#{page.selectedName}">
     <f:selectItems value="#{page.names}"/>
</h:selectOneMenu>

支持Bean

   List<SelectItem> names = new ArrayList<SelectItem>();

   //-- Populate list from database

   names.add(new SelectItem(valueObject,"label"));

   //-- setter/getter accessor methods for list
List name=new ArrayList();
//--从数据库填充列表
名称。添加(新的SelectItem(valueObject,“标签”);
//--列表的setter/getter访问器方法

要显示特定的选定记录,它必须是列表中的一个值。

根据您的问题历史记录,您使用的是JSF 2.x。下面是一个针对JSF2.x的答案。在JSF1.x中,您将被迫在丑陋的实例中包装项值/标签。幸运的是,这在JSF2.x中不再需要了


基本示例 要直接回答您的问题,只需使用其
指向一个
列表
属性,该属性在bean(post)构造期间从DB中保留。下面是一个基本的启动示例,假设
T
实际上表示
字符串



作为可用项的复杂对象 每当
T
涉及一个复杂对象(javabean),例如
User
,它具有
name
String
属性,那么您就可以使用
var
属性来获取迭代变量,您可以依次在
itemValue
和/或
itemLabel
属性中使用该变量(如果省略
项目标签
,则标签将与值相同)

示例#1:


(请注意,
转换器
有点不成熟,以便能够在JSF转换器中注入
@EJB
;通常会将其注释为
@FacesConverter(forClass=User.class)
,)

别忘了确保复杂对象类具有,否则JSF将在渲染过程中无法显示预选项,您将在提交面上看到


具有通用转换器的复杂对象 请看下面的答案:


没有自定义转换器的复杂对象 JSF实用程序库提供了一个特殊的现成转换器,允许您在
中使用复杂对象,而无需创建自定义转换器。只需根据
中现成的项目进行转换



另见:
将复杂对象的通用转换器作为选定项滚动 Balusc在这个问题上给出了一个非常有用的概述性答案。但有一个他没有给出的替代方案:Roll your own generic converter,它将复杂对象作为所选项进行处理。如果要处理所有情况,这非常复杂,但对于简单情况,这非常简单

下面的代码包含这样一个转换器的示例。它的工作原理与OmniFaces相同,因为它查看
UISelectItem的组件的子级
包含对象。区别在于它只处理到实体对象的简单集合或字符串的绑定。它不处理项目组、
SelectItem
s的集合、数组以及其他很多东西

组件绑定到的实体必须实现
IdObject
接口。(这可以通过其他方式解决,例如使用
toString

请注意,实体必须以相同ID的两个实体比较相等的方式实现
equals

要使用它,只需将其指定为select组件上的转换器,绑定到实体属性和可能的实体列表:

<h:selectOneMenu value="#{bean.user}" converter="selectListConverter">
  <f:selectItem itemValue="unselected" itemLabel="Select user..."/>
  <f:selectItem itemValue="empty" itemLabel="No user"/>
  <f:selectItems value="#{bean.users}" var="user" itemValue="#{user}" itemLabel="#{user.name}" />
</h:selectOneMenu>

转换器:

/**
 * A converter for select components (those that have select items as children).
 * 
 * It convertes the selected value string into one of its element entities, thus allowing
 * binding to complex objects.
 * 
 * It only handles simple uses of select components, in which the value is a simple list of
 * entities. No ItemGroups, arrays or other kinds of values.
 * 
 * Items it binds to can be strings or implementations of the {@link IdObject} interface.
 */
@FacesConverter("selectListConverter")
public class SelectListConverter implements Converter {

  public static interface IdObject {
    public String getDisplayId();
  }

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value == null || value.isEmpty()) {
      return null;
    }

    return component.getChildren().stream()
      .flatMap(child -> getEntriesOfItem(child))
      .filter(o -> value.equals(o instanceof IdObject ? ((IdObject) o).getDisplayId() : o))
      .findAny().orElse(null);
  }

  /**
   * Gets the values stored in a {@link UISelectItem} or a {@link UISelectItems}.
   * For other components returns an empty stream.
   */
  private Stream<?> getEntriesOfItem(UIComponent child) {
    if (child instanceof UISelectItem) {
      UISelectItem item = (UISelectItem) child;
      if (!item.isNoSelectionOption()) {
        return Stream.of(item.getValue());
      }

    } else if (child instanceof UISelectItems) {
      Object value = ((UISelectItems) child).getValue();

      if (value instanceof Collection) {
        return ((Collection<?>) value).stream();
      } else {
        throw new IllegalStateException("Unsupported value of UISelectItems: " + value);
      }
    }

    return Stream.empty();
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value == null) return null;
    if (value instanceof String) return (String) value;
    if (value instanceof IdObject) return ((IdObject) value).getDisplayId();

    throw new IllegalArgumentException("Unexpected value type");
  }

}
/**
*用于选择组件(将选择项作为子项的组件)的转换器。
* 
*它将选定的值字符串转换为其元素实体之一,从而允许
*绑定到复杂对象。
* 
*它只处理select组件的简单使用,其中的值是一个简单的
*实体。没有项目组、数组或其他类型的值。
* 
*它绑定到的项可以是字符串或{@link IdObject}接口的实现。
*/
@FacesConverter(“selectListConverter”)
公共类SelectListConverter实现转换器{
公共静态接口IdObject{
公共字符串getDisplayId();
}
@凌驾
公共对象getAsObject(FacesContext上下文、UIComponent组件、字符串值){
if(value==null | | value.isEmpty()){
返回null;
}
返回组件.getChildren().stream()
.flatMap(child->getEntriesFitem(child))
.filter(o->value.equals(o IdObject的实例?((IdObject)o).getDisplayId():o))
.findAny().orElse(null);
}
/**
*获取存储在{@link UISelectItem}或{@link UISelectItems}中的值。
*对于其他组件,返回一个空流。
*/
私有流GetEntriesFitem(UIComponent子级){
if(UISelectItem的子实例){
UISelectItem=(UISelectItem)子项;
如果(!item.isNoSelectionOption()){
返回流.of(item.getValue());
}
}else if(UISelectItems的子实例){
对象值=((UISelectItems)子项).getValue();
if(集合的值实例){
返回((集合)值).stream();
}否则{
抛出新的IllegalStateException(“UISelectItems不支持的值:“+value”);
}
}
返回Stream.empty();
}
@凌驾
公共字符串getAsString(FacesContext上下文、UIComponent、对象值){
if(value==null)返回null;
if(value instanceof String)返回(String)值;
如果
private String userName;
private List<User> users;

@EJB
private UserService userService;

@PostConstruct
public void init() {
    users = userService.list();
}

// ... (getters, setters, etc)
private Long userId;
private List<User> users;

// ... (the same as in previous bean example)
private User user;
private List<User> users;

// ... (the same as in previous bean example)
@ManagedBean
@RequestScoped
public class UserConverter implements Converter {

    @EJB
    private UserService userService;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        if (submittedValue == null || submittedValue.isEmpty()) {
            return null;
        }

        try {
            return userService.find(Long.valueOf(submittedValue));
        } catch (NumberFormatException e) {
            throw new ConverterException(new FacesMessage(String.format("%s is not a valid User ID", submittedValue)), e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        if (modelValue == null) {
            return "";
        }

        if (modelValue instanceof User) {
            return String.valueOf(((User) modelValue).getId());
        } else {
            throw new ConverterException(new FacesMessage(String.format("%s is not a valid User", modelValue)), e);
        }
    }

}
public class User {

    private Long id;

    @Override
    public boolean equals(Object other) {
        return (other != null && getClass() == other.getClass() && id != null)
            ? id.equals(((User) other).id)
            : (other == this);
    }

    @Override
    public int hashCode() {
        return (id != null) 
            ? (getClass().hashCode() + id.hashCode())
            : super.hashCode();
    }

}
<h:selectOneMenu value="#{bean.user}" converter="selectListConverter">
  <f:selectItem itemValue="unselected" itemLabel="Select user..."/>
  <f:selectItem itemValue="empty" itemLabel="No user"/>
  <f:selectItems value="#{bean.users}" var="user" itemValue="#{user}" itemLabel="#{user.name}" />
</h:selectOneMenu>
/**
 * A converter for select components (those that have select items as children).
 * 
 * It convertes the selected value string into one of its element entities, thus allowing
 * binding to complex objects.
 * 
 * It only handles simple uses of select components, in which the value is a simple list of
 * entities. No ItemGroups, arrays or other kinds of values.
 * 
 * Items it binds to can be strings or implementations of the {@link IdObject} interface.
 */
@FacesConverter("selectListConverter")
public class SelectListConverter implements Converter {

  public static interface IdObject {
    public String getDisplayId();
  }

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value == null || value.isEmpty()) {
      return null;
    }

    return component.getChildren().stream()
      .flatMap(child -> getEntriesOfItem(child))
      .filter(o -> value.equals(o instanceof IdObject ? ((IdObject) o).getDisplayId() : o))
      .findAny().orElse(null);
  }

  /**
   * Gets the values stored in a {@link UISelectItem} or a {@link UISelectItems}.
   * For other components returns an empty stream.
   */
  private Stream<?> getEntriesOfItem(UIComponent child) {
    if (child instanceof UISelectItem) {
      UISelectItem item = (UISelectItem) child;
      if (!item.isNoSelectionOption()) {
        return Stream.of(item.getValue());
      }

    } else if (child instanceof UISelectItems) {
      Object value = ((UISelectItems) child).getValue();

      if (value instanceof Collection) {
        return ((Collection<?>) value).stream();
      } else {
        throw new IllegalStateException("Unsupported value of UISelectItems: " + value);
      }
    }

    return Stream.empty();
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value == null) return null;
    if (value instanceof String) return (String) value;
    if (value instanceof IdObject) return ((IdObject) value).getDisplayId();

    throw new IllegalArgumentException("Unexpected value type");
  }

}
@Named
@ViewScoped
public class ViewScopedFacesConverter implements Converter, Serializable
{
        private static final long serialVersionUID = 1L;
        private Map<String, Object> converterMap;

        @PostConstruct
        void postConstruct(){
            converterMap = new HashMap<>();
        }

        @Override
        public String getAsString(FacesContext context, UIComponent component, Object object) {
            String selectItemValue = String.valueOf( object.hashCode() ); 
            converterMap.put( selectItemValue, object );
            return selectItemValue;
        }

        @Override
        public Object getAsObject(FacesContext context, UIComponent component, String selectItemValue){
            return converterMap.get(selectItemValue);
        }
}
 <f:converter binding="#{viewScopedFacesConverter}" />
<p:selectOneListbox id="adminEvents" value="#{testBean.selectedEvent}">