2

在一个 JSF 项目中,我有一个由字符串值列表填充的 SelectOneMenu,并连接到一个整数值“yearStart”。当我从列表中选择一个值时,转换器总是输出到控制台“stringVal = null”。为什么所选项目的值没有到达转换器?

我的网页包括以下内容:

<h:selectOneMenu value="#{applicantController.yearStart}">
    <f:selectItems value="#{yearList.years}" />
    <f:converter converterId="studyYearConverter"/>
</h:selectOneMenu>

它使用以下年份列表:

@ManagedBean
@ApplicationScoped
public class YearList implements Serializable {

    private static final long serialVersionUID = 1L;

    private final List<String> years = Arrays.asList("prior to 1990", "1990",
        "1991", "1992", "1993", "1994", "1995", "1996", "1997", "1998",
        "1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006",
        "2007", "2008", "2009", "2010", "2011", "2012", "2013");

    public List<String> getYears() {
        return years;
    }

}

我的转换器类:

@FacesConverter(value = "studyYearConverter")
public class StudyYearConverter implements Converter {

    private static final String PRIOR_TO_1990 = "prior to 1990";

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String stringVal) {
        if (PRIOR_TO_1990.equals(stringVal)) {
            return -1;
        } else {
            System.out.println("stringVal = " + stringVal);  
            // Why is this alway null??
            try {
                return Integer.parseInt(stringVal);
            } catch (NumberFormatException pe) {
                FacesMessage message = new FacesMessage(
                       "Invalid date format. Valid format e.g. 2010-04");
                throw new ConverterException(message);
            }
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
        Object value) {
        if (value == null || !(value instanceof Integer)) {
                return null;
        } else {
            Integer year = (Integer) value;
            if (year == -1) {
                return PRIOR_TO_1990;
            } else {
                return year.toString();
            }
        }
    }
}
4

2 回答 2

0

您没有提供转换器期望的项目。

getAsString()方法在呈现 HTML 响应期间使用。此时,(可能)复杂的 Java 对象需要转换为其唯一的String表示,以便它们可以在 HTML 中表示。该getAsObject()方法在应用 HTTP 请求参数值期间使用。HTTP 请求参数值可以像 HTML 输入值一样仅表示为String,为了返回复杂的 Java 对象,String必须转换唯一表示。

你有一个List<String>可用的项目值。因此,当每个项目都将要呈现为 HTML 时,它会通过getAsString(). 但是,您正在执行instanceof Integer检查,该检查总是会失败并因此返回null每个项目。因此,您最终<option>会在生成的 HTML 中以null. 这就是你getAsObject()最终得到nulls 的原因。

根据迄今为止的尝试,我的印象#{applicantController.yearStart}实际上是Integer您想要设置的年份,或者-1如果选择了“1990 年之前”。如果您想保留转换器,那么您应该将可用项目更改为

private final List<Integer> years = Arrays.asList(-1, 1990,
        1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
        1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
        2007, 2008, 2009, 2010, 2011, 2012, 2013);
于 2013-02-11T12:50:39.737 回答
-1

I know which could be the solution. You should store the list and selected element in properties and maintain them in the scope as long as the component is used.

于 2013-08-29T14:20:28.043 回答