使用Java Server Faces将多个输入字段绑定到backing bean属性?

时间:2009-12-18 20:41:47

标签: java jsf binding seam

假设我有一个月,日和年选择。每一个选择一个。现在我需要将它们绑定到一个支持bean属性 - java.util.Date。我如何实现目标?

2 个答案:

答案 0 :(得分:2)

三种方式:

  1. java.util.Calendar为后退或中间,有三个吸气剂和三个吸气剂。
  2. 使用Converter,但这有点像hacky。
  3. 使用rich:calendar等第三方组件。
  4. 根据评论

    编辑,以下是选项2的外观。

    page.jsp

    <h:form>
        <h:selectOneMenu value="#{myBean.date}">
            <f:converter converterId="datePartConverter" />
            <f:attribute name="part" value="day" />
            <f:selectItems value="#{myBean.days}" />
        </h:selectOneMenu>
        <h:selectOneMenu value="#{myBean.date}">
            <f:converter converterId="datePartConverter" />
            <f:attribute name="part" value="month" />
            <f:selectItems value="#{myBean.months}" />
        </h:selectOneMenu>
        <h:selectOneMenu value="#{myBean.date}">
            <f:converter converterId="datePartConverter" />
            <f:attribute name="part" value="year" />
            <f:selectItems value="#{myBean.years}" />
        </h:selectOneMenu>
    
        <h:commandButton value="submit" action="#{myBean.submit}"/>
        <h:messages />
    </h:form>
    

    mypackage.MyBean

    package mypackage;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import javax.faces.model.SelectItem;
    
    public class MyBean {
    
        private static List<SelectItem> days = new ArrayList<SelectItem>();
        private static List<SelectItem> months = new ArrayList<SelectItem>();
        private static List<SelectItem> years = new ArrayList<SelectItem>();
    
        static {
            // Just do your thing to fill them. Only ensure that those are Strings,
            // else you'll need to change the type in Converter accordingly.
            for (int i = 1; i <= 31; i++) days.add(new SelectItem(String.valueOf(i)));
            for (int i = 1; i <= 12; i++) months.add(new SelectItem(String.valueOf(i)));
            for (int i = 2000; i <= 2020; i++) years.add(new SelectItem(String.valueOf(i)));
        }
    
        private Date date;
    
        public void submit() {
            // Print submitted date to stdout.
            System.out.println("Submitted date: " + date);
        }
    
        public List<SelectItem> getDays() {
            return days;
        }
    
        public List<SelectItem> getMonths() {
            return months;
        }
    
        public List<SelectItem> getYears() {
            return years;
        }
    
        public Date getDate() {
            return date;
        }
    
        public void setDate(Date date) {
            this.date = date;
        }
    
    }
    

    mypackage.DatePartConverter

    package mypackage;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Map;
    
    import javax.faces.application.FacesMessage;
    import javax.faces.component.UIComponent;
    import javax.faces.component.UIInput;
    import javax.faces.context.FacesContext;
    import javax.faces.convert.Converter;
    import javax.faces.convert.ConverterException;
    
    public class DatePartConverter implements Converter {
    
        public Object getAsObject(FacesContext context, UIComponent component, String value) {
            String part = (String) component.getAttributes().get("part");
            Date date = null;
    
            if (context.getRenderResponse()) {
                // Convert any default/selected date for display.
                Date selectedDate = (Date) ((UIInput) component).getValue();
                if (selectedDate != null) {
                    if (("day".equals(part) && new SimpleDateFormat("d").format(selectedDate).equals(value))
                        || ("month".equals(part) && new SimpleDateFormat("M").format(selectedDate).equals(value))
                        || ("year".equals(part) && new SimpleDateFormat("yyyy").format(selectedDate).equals(value)))
                    {
                        date = selectedDate;
                    }
                }
            } else {
                // Convert submitted date after submit.
                Map<String, Object> map = context.getExternalContext().getRequestMap();
                if ("day".equals(part)) {
                    map.put("DatePartConverter.day", value); // Save until we have all parts.
                } else if ("month".equals(part)) {
                    map.put("DatePartConverter.month", value); // Save until we have all parts.
                } else if ("year".equals(part)) {
                    String day = (String) map.get("DatePartConverter.day");
                    String month = (String) map.get("DatePartConverter.month");
                    String dateString = String.format("%s-%s-%s", day, month, value);
    
                    try {
                        date = new SimpleDateFormat("d-M-yyyy").parse(dateString);
                    } catch (ParseException e) {
                        throw new ConverterException(new FacesMessage(e.getMessage()), e);
                    }
                }
            }
    
            return date;
        }
    
    }
    
        public String getAsString(FacesContext context, UIComponent component, Object value) {
            // Not relevant here. Just return SelectItem's value.
            return (String) value;
        }
    

    faces-config.xml

    <converter>
        <converter-id>datePartConverter</converter-id>
        <converter-class>mypackage.DatePartConverter</converter-class>
    </converter>
    
    <managed-bean>
        <managed-bean-name>myBean</managed-bean-name>
        <managed-bean-class>mypackage.MyBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
    

    请注意,没有ValidatorSimpleDateFormat默认为lenient。因此,选择例如11月31日将产生12月1日。如果您想要警告,可能需要自己实施DatePartValidator

答案 1 :(得分:0)

当说“绑定”和“支持bean”时,你应该参考以下内容:

<h:inputText binding="#{myBean.myTextField}" />

并在您的bean中有private UIInput

如果是这种情况 - 不,你不能这样绑定。好吧,我不确定你在技术上是否可以 - 但肯定会有意想不到的效果。

但是,如果您想要定位托管bean属性,那么您可以,例如:

<h:inputText value="#{myBean.myProperty.day}" />
<h:inputText value="#{myBean.myProperty.year}" />